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?
6 réponses
une alternative à grep
est which
:
df.2 <- df[, -which(names(df) %in% c("name1", "name2", "name3"))]
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.
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
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.
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.
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).