variable - subset r studio




Supprimer les colonnes du cadre de données par nom (11)

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.


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) )]

Il y a aussi la commande subset , 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 supprimer les colonnes a, c vous pouvez faire:

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

Je continue à penser qu'il doit y avoir un meilleur idiome, mais pour la soustraction des colonnes par nom, j'ai tendance à faire ce qui suit:

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

# return everything except a and c
df <- df[,-match(c("a","c"),names(df))]
df

Je doute que cela attire beaucoup d'attention ici, mais si vous avez une liste de colonnes que vous voulez supprimer, et que vous voulez le faire dans une chaîne dplyr , j'utilise one_of() dans la clause select :

Voici un exemple simple et reproductible:

undesired <- c('mpg', 'cyl', 'hp')

mtcars %>%
  select(-one_of(undesired))

La documentation peut être trouvée en exécutant ?one_of ou ici:

http://genomicsclass.github.io/book/pages/dplyr_tutorial.html


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

Vous pouvez passer un nom de vecteur de caractères à gauche de l'opérateur := , et NULL comme 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 de [ , enroulez le nom de l'objet dans () ou {} pour forcer l'évaluation de LHS dans l'étendue appelante comme nom dans la portée 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 également utiliser set , ce qui évite le surcoût de [.data.table , et fonctionne 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)

Une autre possibilité:

df <- df[, setdiff(names(df), c("a", "c"))]

ou

df <- df[, grep('^(a|c)$', names(df), invert=TRUE)]

Une autre solution si vous ne voulez pas utiliser @ hadley ci-dessus: Si "COLUMN_NAME" est le nom de la colonne que vous voulez supprimer:

df[,-which(names(df) == "COLUMN_NAME")]

Voici une manière dplyr s'y prendre:

#df[ -c(1,3:6, 12) ]  # original
df.cut <- df %>% select(-col.to.drop.1, -col.to.drop.2, ..., -col.to.drop.6)  # with dplyr::select()

J'aime ça parce que c'est intuitif à lire et à comprendre sans annotation et robuste aux colonnes qui changent de position dans le cadre de données. Il suit également l'idiome vectorisé en utilisant - pour supprimer des éléments.


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]

EDIT: Pour ceux qui ne connaissent pas encore l'argument drop 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 le mentionne pas) supprimera les dimensions inutiles, et retournera donc un vecteur avec les valeurs de la colonne y .


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"

within(df, rm(x))

est probablement le plus facile, ou pour plusieurs variables:

within(df, rm(x, y))

Ou si vous traitez avec data.table s (per Comment supprimez-vous 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")]




r-faq