Question Supprimer les colonnes du cadre de données par nom


J'ai un certain nombre de colonnes que je voudrais supprimer d'un cadre de données. Je sais que nous pouvons les supprimer individuellement en utilisant quelque chose comme:

df$x <- NULL

Mais j'espérais faire cela avec moins de commandes.

En outre, je sais que je pourrais déposer des colonnes en utilisant l'indexation entière comme ceci:

df <- df[ -c(1, 3:6, 12) ]

Mais je suis inquiet que la position relative de mes variables puisse changer.

Étant donné la puissance de R, j'ai pensé qu'il pourrait y avoir un meilleur moyen que de laisser tomber chaque colonne une par une.


668
2018-01-05 14:34


origine


Réponses:


Vous pouvez utiliser une simple liste de noms:

DF <- data.frame(
  x=1:10,
  y=10:1,
  z=rep(5,10),
  a=11:20
)
drops <- c("x","z")
DF[ , !(names(DF) %in% drops)]

Ou, alternativement, vous pouvez faire une liste de ceux à garder et se référer à eux par leur nom:

keeps <- c("y", "a")
DF[keeps]

MODIFIER : Pour ceux qui ne connaissent pas encore le drop argument de la fonction d'indexation, si vous voulez garder une colonne comme trame de données, vous faites:

keeps <- "y"
DF[ , keeps, drop = FALSE]

drop=TRUE (ou ne pas le mentionner) va laisser tomber les dimensions inutiles, et donc retourner un vecteur avec les valeurs de la colonne y.


729
2018-01-05 14:40



Il y a aussi le subset commande, utile si vous connaissez les colonnes que vous voulez:

df <- data.frame(a = 1:10, b = 2:11, c = 3:12)
df <- subset(df, select = c(a, c))

MISE À JOUR après un commentaire par @hadley: Pour laissez tomber colonnes a, c vous pourriez faire:

df <- subset(df, select = -c(a, c))

352
2018-01-05 14:52



within(df, rm(x))

est probablement le plus facile, ou pour plusieurs variables:

within(df, rm(x, y))

Ou si vous avez affaire à data.tables (par Comment supprimer une colonne par son nom dans data.table?):

dt[, x := NULL]   # deletes column x by reference instantly

dt[, !"x", with=FALSE]   # selects all but x into a new data.table

ou pour plusieurs variables

dt[, c("x","y") := NULL]

dt[, !c("x", "y"), with=FALSE]

Dans la version de développement de data.table (instructions d'installation), with = FALSE n'est plus nécessaire:

dt[ , !"x"]
dt[ , !c("x", "y")]

115
2017-09-28 22:28



Vous pourriez utiliser %in% comme ça:

df[, !(colnames(df) %in% c("x","bar","foo"))]

90
2018-01-05 14:40



list (NULL) fonctionne également:

dat <- mtcars
colnames(dat)
# [1] "mpg"  "cyl"  "disp" "hp"   "drat" "wt"   "qsec" "vs"   "am"   "gear"
# [11] "carb"
dat[,c("mpg","cyl","wt")] <- list(NULL)
colnames(dat)
# [1] "disp" "hp"   "drat" "qsec" "vs"   "am"   "gear" "carb"

38
2018-02-12 05:34



Si vous voulez supprimer les colonnes par référence et éviter la copie interne associée à data.frames alors vous pouvez utiliser le data.table paquet et la fonction :=

Vous pouvez passer un nom de vecteur de caractères sur le côté gauche de la := opérateur, et NULL comme le RHS.

library(data.table)

df <- data.frame(a=1:10, b=1:10, c=1:10, d=1:10)
DT <- data.table(df)
# or more simply  DT <- data.table(a=1:10, b=1:10, c=1:10, d=1:10) #

DT[, c('a','b') := NULL]

Si vous souhaitez prédéfinir les noms en tant que vecteur de caractères en dehors de l'appel à [, envelopper le nom de l'objet dans () ou {} pour forcer le LHS à être évalué dans la portée d'appel pas comme un nom dans le champ de DT.

del <- c('a','b')
DT <- data.table(a=1:10, b=1:10, c=1:10, d=1:10)
DT[, (del) := NULL]
DT <-  <- data.table(a=1:10, b=1:10, c=1:10, d=1:10)
DT[, {del} := NULL]
# force or `c` would also work.   

Vous pouvez aussi utiliser set, ce qui évite les frais généraux [.data.table, et travaille aussi pour data.frames!

df <- data.frame(a=1:10, b=1:10, c=1:10, d=1:10)
DT <- data.table(df)

# drop `a` from df (no copying involved)

set(df, j = 'a', value = NULL)
# drop `b` from DT (no copying involved)
set(DT, j = 'b', value = NULL)

36
2017-11-14 01:02



Il existe une stratégie potentiellement plus puissante basée sur le fait que grep () retournera un vecteur numérique. Si vous avez une longue liste de variables comme dans un de mes ensembles de données, certaines variables se terminent par ".A" et d'autres par ".B" et vous ne voulez que celles qui se terminent par ".A" (le long avec toutes les variables qui ne correspondent à aucun modèle, faites ceci:

dfrm2 <- dfrm[ , -grep("\\.B$", names(dfrm)) ]

Pour l'exemple, en utilisant l'exemple de Joris Meys, il pourrait ne pas être aussi compact, mais ce serait:

DF <- DF[, -grep( paste("^",drops,"$", sep="", collapse="|"), names(DF) )]

34
2018-01-05 21:50



Par intérêt, ceci signale l'une des étranges incohérences de syntaxe multiples de R. Par exemple étant donné une trame de données à deux colonnes:

df <- data.frame(x=1, y=2)

Cela donne un cadre de données

subset(df, select=-y)

mais cela donne un vecteur

df[,-2]

Tout est expliqué dans ?[ mais ce n'est pas exactement le comportement attendu. Eh bien, au moins pas à moi ...


19
2018-05-02 18:42