web-dev-qa-db-fra.com

R dplyr: Supprimer plusieurs colonnes

J'ai une base de données et une liste de colonnes dans cette base de données que j'aimerais supprimer. Utilisons le jeu de données iris comme exemple. J'aimerais supprimer Sepal.Length et Sepal.Width et n'utiliser que les colonnes restantes. Comment faire cela en utilisant select ou select_ à partir du package dplyr?

Voici ce que j'ai essayé jusqu'à présent:

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

Erreur dans -drop.cols: argument non valide pour l'opérateur unaire

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

Erreur dans -drop.cols: argument non valide pour l'opérateur unaire

iris %>% select(!drop.cols)

Erreur dans! Drop.cols: type d'argument invalide

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

Erreur dans! Drop.cols: type d'argument invalide

J'ai l'impression qu'il me manque quelque chose d'évident car cela semble être une opération assez utile qui devrait déjà exister. Sur Github, quelqu'un a posté n problème similaire , et Hadley a déclaré utiliser "l'indexation négative". C'est ce que (je pense) j'ai essayé, mais en vain. Aucune suggestion?

66

Consultez l'aide sur select_vars. Cela vous donne quelques idées supplémentaires sur la façon de travailler avec cela.

Dans ton cas:

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

essayez aussi

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

Au-delà de select(-one_of(drop.cols)), il existe deux autres options pour supprimer des colonnes à l'aide de select() qui n'impliquent pas la définition de tous les noms de colonnes spécifiques (à l'aide des exemples de données dplyr starwars pour une plus grande variété de noms de colonnes):

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 
23
sbha

Soyez prudent avec la fonction select(), car elle est utilisée à la fois dans les packages dplyr et MASS. Par conséquent, si MASS est chargé, select () risque de ne pas fonctionner correctement. Pour savoir quels packages sont chargés, tapez sessionInfo() et cherchez-le dans la section "autres packages joints:". S'il est chargé, tapez detach( "package:MASS", unload = TRUE ) et votre fonction select() devrait fonctionner à nouveau.

5
Durand Sinclair

Nous pouvons essayer

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

Une autre méthode consiste à muter les colonnes indésirables en NULL, pour éviter les parenthèses incorporées:

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
2
Moody_Mudskipper

Si vous avez un caractère spécial dans les noms de colonne, il est possible que select ou select_ ne fonctionne pas comme prévu. Cette propriété de dplyr d'utiliser ".". Pour faire référence au jeu de données dans la question, la ligne suivante peut être utilisée pour résoudre ce problème:

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