R dplyr: rilascia più colonne


96

Ho un dataframe e un elenco di colonne in quel dataframe che vorrei eliminare. Usiamo il irisset di dati come esempio. Mi piacerebbe far cadere Sepal.Lengthed Sepal.Widthe utilizzare solo le colonne rimanenti. Come posso farlo usando selecto select_dal dplyrpacchetto?

Ecco cosa ho provato finora:

drop.cols <- c('Sepal.Length', 'Sepal.Width')
iris %>% select(-drop.cols)

Errore in -drop.cols: argomento non valido per l'operatore unario

iris %>% select_(.dots = -drop.cols)

Errore in -drop.cols: argomento non valido per l'operatore unario

iris %>% select(!drop.cols)

Errore in! Drop.cols: tipo di argomento non valido

iris %>% select_(.dots = !drop.cols)

Errore in! Drop.cols: tipo di argomento non valido

Mi sento come se mi mancasse qualcosa di ovvio perché sembra un'operazione piuttosto utile che dovrebbe già esistere. Su Github, qualcuno ha pubblicato un problema simile e Hadley ha detto di usare "indicizzazione negativa". Questo è quello che (penso) ho provato, ma senza alcun risultato. Eventuali suggerimenti?

Risposte:


127

Controlla la guida su select_vars. Questo ti dà alcune idee in più su come lavorare con questo.

Nel tuo caso:

iris %>% select(-one_of(drop.cols))

Grazie. Per qualche ragione, funziona iris, ma non sul mio dataframe effettivo ( irisera un esempio di giocattolo). Il mio dataframe contiene 4558 righe e 147 colonne. Il messaggio di errore che ho ricevuto era Error in eval(x$expr, data, x$env) : variable names are limited to 10000 bytes. Qualche idea del perché potrebbe succedere?
Navaneethan Santhanam

1
Ah, sembra che stessi facendo un errore. Ho usato accidentalmente al select_varsposto di select. Ora funziona perfettamente!
Navaneethan Santhanam

5
Dove dovremmo trovare informazioni sulle funzioni integrate come one_of? A meno che non mi manchi qualcosa, non appare nella documentazione del pacchetto ( help(package='dplyr')).
geoteoria

4
@geotheory, in realtà one_of è documentato. vedere help(one_of, package = "dplyr"). Almeno è nella versione del pacchetto 0.5.0. Ma aiuta a leggere i blog che Hadley pubblica quando ci sono aggiornamenti a uno dei suoi pacchetti. E alcune funzioni sono documentate all'interno di altre funzioni. Sfortunatamente ciò richiede la lettura di tutta la documentazione, cosa che faccio principalmente quando voglio qualcosa che non è immediatamente ovvio o possibile con la funzione.
phiver

10
Grazie. Come si scoprono queste funzioni in primo luogo, in termini di documentazione?
geoteoria

67

anche provare

## Notice the lack of quotes
iris %>% select (-c(Sepal.Length, Sepal.Width))

5
Grande! Veramente utile quando dobbiamo eliminare le colonne copiando e incollando i nomi dalla console.
Pablo Casas

37

Inoltre select(-one_of(drop.cols))ci sono un paio di altre opzioni per eliminare le colonne utilizzando select()che non implicano la definizione di tutti i nomi di colonna specifici (utilizzando i dati di esempio di dplyr starwars per una maggiore varietà di nomi di colonna):

starwars %>% 
  select(-(name:mass)) %>%        # the range of columns from 'name' to 'mass'
  select(-contains('color')) %>%  # any column name that contains 'color'
  select(-starts_with('bi')) %>%  # any column name that starts with 'bi'
  select(-ends_with('er')) %>%    # any column name that ends with 'er'
  select(-matches('^f.+s$')) %>%  # any column name matching the regex pattern
  select_if(~!is.list(.)) %>%     # not by column name but by data type
  head(2)

# A tibble: 2 x 2
homeworld species
  <chr>     <chr>  
1 Tatooine  Human  
2 Tatooine  Droid 

È select_if(~!is.list(.))equivalente a select_if(is.list(.))?
Jasha

3
In questo caso ~è una scorciatoia per definire una funzione anonima, non è un altro simbolo per non. Ad esempio, questi due significano la stessa cosa function(x) {!is.list(x)}e ~!is.list(.). pensa a ~come scorciatoia per function(.).
SlyFox

8

select()Fai attenzione alla funzione, perché è usata sia nei pacchetti dplyr che MASS, quindi se MASS è caricato, select () potrebbe non funzionare correttamente. Per scoprire quali pacchetti sono stati caricati, digitarli sessionInfo()e cercarli nella sezione "altri pacchetti allegati:". Se è caricato, digita detach( "package:MASS", unload = TRUE )e la tua select()funzione dovrebbe funzionare di nuovo.


12
in alternativa è possibile accedere alla funzione direttamente nello spazio dei nomi del pacchetto in questo modo dplyr::select().
Triamus

2
Troppo spesso mi sono imbattuto in questo problema. Ora di solito definisco una nuova funzione all'inizio del mio script dselect <- dplyr::select().
filups21

5

Possiamo provarci

iris %>% 
      select_(.dots= setdiff(names(.),drop.cols))

Grazie @akrun, ha funzionato perfettamente. Tuttavia, dato il clamore che circonda dplyrla capacità di rendere le attività di analisi di base facili da leggere e scrivere, sono deluso dal fatto che la soluzione effettiva appaia come una soluzione alternativa.
Navaneethan Santhanam

@NavaneethanSanthanam In realtà, l' one_ofaltra soluzione è la strada da percorrere. Me ne sono dimenticato.
akrun

3

Un altro modo è modificare le colonne indesiderate in NULL, questo evita le parentesi incorporate:

head(iris,2) %>% mutate_at(drop.cols, ~NULL)
#   Petal.Length Petal.Width Species
# 1          1.4         0.2  setosa
# 2          1.4         0.2  setosa

Anche questo non dà un avviso se una colonna non è presente.
skoz

3

Se si dispone di un carattere speciale nei nomi delle colonne, sia selecto select_non può funzionare come previsto. Questa proprietà dplyrdi utilizzo ".". Per fare riferimento al set di dati nella domanda, la seguente riga può essere utilizzata per risolvere questo problema:

drop.cols <- c('Sepal.Length', 'Sepal.Width')
  iris %>% .[,setdiff(names(.),drop.cols)]

Le risposte solo al codice sono scoraggiate. Fornisci alcune spiegazioni su come funziona la risposta e su come differisce dalle risposte già presenti.
Ralf Stubner

Grazie!! Nessuna delle altre soluzioni sopra ha funzionato per questo motivo esatto.
Marty999

0

Puoi provare

iris %>% select(-!!drop.cols)
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.