Sélection des colonnes dans la base de données R en fonction de celles *non* dans un vecteur

je sais qu'il est possible d'extraire des colonnes d'un cadre de données R (ou d'une matrice) comme ceci:

df.2 <- df[, c("name1", "name2", "name3")]

mais peut-on utiliser un ! ou un autre outil pour sélectionner toutes les colonnes sauf celles énumérées ?

pour background, j'ai une base de données avec pas mal de vecteurs de colonnes et j'aimerais éviter:

  • taper la majorité des noms alors que je pouvais supprimer une minorité
  • utilisant le beaucoup plus court df.2 <- df[, c(1,3,5)] parce que quand mon .changement de fichier csv, mon code va à heck car la numérotation n'est plus la même. Je suis nouveau à R et je pense que j'ai appris la manière dure de ne pas utiliser les vecteurs de nombre pour les plus grands df qui pourraient changer.

j'ai essayé:

df.2 <- df[, !c("name1", "name2", "name3")]
df.2 <- df[, !=c("name1", "name2", "name3")]

et comme je tapais ceci, j'ai découvert que cela fonctionne:

df.2 <- df[, !names(df) %in% c("name1", "name2", "name3")]

y a-t-il un meilleur moyen que celui-ci dernière?

36
demandé sur Hendy 2012-08-31 06:16:05

6 réponses

une alternative à grep est which :

df.2 <- df[, -which(names(df) %in% c("name1", "name2", "name3"))]
25
répondu harkmug 2017-03-08 05:28:21

vous pouvez faire un appel plus court qui est aussi plus généralisable avec négatif-grep:

df.2 <- df[, -grep("^name[1:3]$", names(df) )] 

puisque grep renvoie des nombres, vous pouvez utiliser l'indexation vectorielle négative pour supprimer les colonnes. Vous pouvez ajouter de nouvelles ou des modèles plus complexes.

11
répondu 42- 2012-08-31 04:58:00

dplyr::select() a plusieurs options pour supprimer des colonnes spécifiques:

library(dplyr)

drop_columns <- c('cyl','disp','hp')
mtcars %>% 
  select(-one_of(drop_columns)) %>% 
  head(2)

              mpg drat    wt  qsec vs am gear carb
Mazda RX4      21  3.9 2.620 16.46  0  1    4    4
Mazda RX4 Wag  21  3.9 2.875 17.02  0  1    4    4

négation des noms de colonne spécifiques, la colonne "hp" et les colonnes de "qsec" à "gear" sont supprimées comme suit:

mtcars %>% 
  select(-hp, -(qsec:gear)) %>% 
  head(2)

              mpg cyl disp drat    wt carb
Mazda RX4      21   6  160  3.9 2.620    4
Mazda RX4 Wag  21   6  160  3.9 2.875    4

vous pouvez aussi nier contains() , starts_with() , ends_with() , ou matches() :

mtcars %>% 
  select(-contains('t')) %>%
  select(-starts_with('a')) %>% 
  select(-ends_with('b')) %>% 
  select(-matches('^m.+g$')) %>% 
  head(2)

              cyl disp  hp  qsec vs gear
Mazda RX4       6  160 110 16.46  0    4
Mazda RX4 Wag   6  160 110 17.02  0    4
5
répondu sbha 2018-03-29 13:12:58

Vous pourriez faire une fonction personnalisée pour ce faire, si vous l'utilisez pour votre propre usage à manipuler des données. Je peux faire quelque chose comme ceci:

rm.col <- function(df, ...) {
    x <- substitute(...())
    z <- Trim(unlist(lapply(x, function(y) as.character(y))))
    df[, !names(df) %in% z]
}

rm.col(mtcars, hp, mpg)

le premier argument est le nom de la base de données. les ... suivants sont les noms des colonnes que vous souhaitez supprimer.

2
répondu Tyler Rinker 2012-08-31 02:42:56

vieux fil, Mais voici une autre solution:

df.2 <- subset(df, select=-c(name1, name2, name3))

ceci a été posté dans un autre thread similaire (bien que je ne puisse pas le trouver maintenant). Devrait être du code durable dans la situation que vous décrivez, et est probablement plus facile à lire et éditer que certaines des autres options.

2
répondu mfloren 2017-04-25 00:32:16

la façon la plus facile qui me vient à l'esprit:

filtered_df<-df[, setdiff(noms(df),c("nom1","nom2") ]

essentiellement, vous calculez la différence entre la liste complète des noms de colonne et le sous-ensemble que vous voulez filtrer (name1 et name2 ci-dessus).

-1
répondu Ahmed Osman 2015-11-08 01:18:41