Chute de bloc de données de colonnes par leur nom
J'ai un certain nombre de colonnes que je voudrais enlever d'un bloc de données. Je sais que nous pouvons les supprimer individuellement en utilisant quelque chose comme:
df$x <- NULL
Mais j'espérais le faire avec moins de commandes.
Aussi, je sais que je pourrais déplacer des colonnes à l'aide de entier indexation comme ceci:
df <- df[ -c(1, 3:6, 12) ]
Mais je crains que la position relative de mes variables peuvent changer.
Compte tenu de la puissance de R, j'ai pensé qu'il pourrait y avoir une meilleure façon que de laisser tomber chaque colonne, un par un.
- Quelqu'un peut m'expliquer pourquoi la R n'a pas quelque chose de simple comme
df#drop(var_name)
, et au lieu de cela, nous avons besoin de faire compliqué ces solutions de rechange? - Le " sous-ensemble()' en fonction de R est aussi parcimonieuse que la " goutte()' de la fonction en Python, sauf que vous n'avez pas besoin de spécifier l'axe de l'argumentation... je suis d'accord que c'est ennuyeux qu'il ne peut pas être un seul, l'ultime, le simple mot-clé/syntaxe mis en œuvre à travers le conseil d'administration pour quelque chose d'aussi simple que la suppression d'une colonne.
Vous devez vous connecter pour publier un commentaire.
Vous pouvez utiliser une simple liste de noms :
Ou, alternativement, vous pouvez faire une liste de ceux à garder et se référer à eux par leur nom :
EDIT :
Pour ceux pas encore familiarisés avec la
drop
argument de la fonction d'indexation, si vous voulez garder une colonne comme un bloc de données, vous n':drop=TRUE
(ou de ne pas le mentionner) passera inutile dimensions, et donc le retour d'un vecteur avec les valeurs de la colonney
.DF[,keeps]
au lieu deDF[keeps]
?Il y a aussi le
subset
commande, utile si vous connaissez les colonnes que vous souhaitez:Mis à JOUR après le commentaire de @hadley: Pour baisse les colonnes a,c, vous pouvez faire:
subset
fonction a une option comme "allbut = FALSE", qui "inverse" de la sélection lorsque la valeur est TRUE, c'est à dire conserve toutes les colonnes sauf ceux de laselect
liste.df[c("a", "c")]
subset
de commande où vous n'avez pas besoin de mettre des guillemets autour des noms de colonnes -- je suppose que je ne me dérange pas de taper quelques caractères supplémentaires juste pour éviter de citer des noms 🙂subset
à l'intérieur d'autres fonctions.select = -b
ne semble pas fonctionner?est probablement la plus facile, ou de plusieurs variables:
Ou si vous avez affaire à
data.table
s (par Comment supprimer une colonne par nom dans les données.de la table?):ou de plusieurs variables
within(df, rm(x))
est loin la solution la plus propre. Étant donné que c'est une possibilité, tous les autres réponse semble inutilement compliqué par un ordre de grandeur.within(df, rm(x))
sera pas travail si il y a double colonnes nomméesx
dansdf
.df <- data.frame(x = 1, y = 2); names(df) <- c("x", "x"); within(df, rm(x))
retournedata.frame(x = 2, x = 2)
.within()
qui est puissant, mais utilise également NSE. La remarque sur la page d'aide indique clairement que pour la programmation de suffisamment de soin doit être utilisé.Vous pouvez utiliser
%in%
comme ceci:DF[ , !(names(DF) %in% drops)]
identical(post_time_1, post_time_2) [1] TRUE
=Dliste(NULL) fonctionne également:
data.table
ainsi.dat[,c("mpg","cyl","wt")] <- NULL
Si vous souhaitez supprimer les colonnes par référence et d'éviter la copie interne associée à
data.frames
ensuite, vous pouvez utiliser ledata.table
paquet et la fonction:=
Vous pouvez passer d'un caractère de vecteur de noms à la gauche de la
:=
opérateur, etNULL
que le membre de droite.Si vous souhaitez prédéfinir les noms de personnages de vecteur à l'extérieur de l'appel à
[
, enveloppez-le nom de l'objet dans()
ou{}
à force de GAUCHE à être évalués dans le contexte appelant non pas comme un nom dans le champ d'application deDT
.Vous pouvez également utiliser
set
, ce qui évite la surcharge de[.data.table
, et fonctionne également pour lesdata.frames
!Il est potentiellement plus puissant de la stratégie basée sur le fait que grep() retourne un vecteur numérique. Si vous avez une longue liste de variables comme je le fais dans un de mes jeu de données, certaines variables qui se terminent par ".Un" et d'autres qui se terminent par ".B" et que vous souhaitez seulement ceux qui se terminent par ".Un" (avec toutes les variables qui ne correspondent pas, en soit le motif, ce faire:
Pour le cas à portée de main, à l'aide de Joris Meys exemple, il pourrait ne pas être aussi compact, mais il serait:
drops
en premier lieu commepaste0("^", drop_cols, "$")
, cela devient beaucoup plus agréable (lire: plus compact) avecsapply
:DF[ , -sapply(drops, grep, names(DF))]
Un autre
dplyr
réponse. Si vos variables ont en commun certaines structure de la nomenclature, vous pouvez essayer destarts_with()
. Par exempleSi vous souhaitez déposer une séquence de variables dans le bloc de données, vous pouvez utiliser
:
. Par exemple, si vous avez voulu tombervar2
,var3
, et tous variables entre les deux, vous devriez juste être laissé avecvar1
:select()
, commecontains()
oumatches()
, qui accepte également les regex.De sortie:
De sortie:
D'intérêt, ce drapeaux de l'un de R est bizarre multiples syntaxe des incohérences. Pour l'exemple donné à deux colonnes trame de données:
Cela donne une trame de données
mais cela donne un vecteur
Tout est expliqué dans
?[
mais ce n'est pas exactement un comportement attendu. Eh bien au moins, pas pour moi...Une autre possibilité:
ou
setdiff
est le meilleur en particulier dans le cas d'un très grand nombre de colonnes.df <- df[ , -which(grepl('a|c', names(df)))]
Dplyr Solution
Je doute que cela attire beaucoup d'attention ici-bas, mais si vous avez une liste de colonnes que vous souhaitez supprimer, et vous voulez le faire dans un
dplyr
de la chaîne d'-je utiliserone_of()
dans leselect
clause:Ici est un simple, reproduit exemple:
Documentation peut être trouvée en exécutant
?one_of
ou ici:http://genomicsclass.github.io/book/pages/dplyr_tutorial.html
Ici est un
dplyr
façon d'aller à ce sujet:J'aime cela parce que c'est de l'intuition à lire & comprendre sans annotation et robuste pour les colonnes de changer de position à l'intérieur de la trame de données. Il suit également les vectorisé idiome à l'aide de
-
pour supprimer des éléments.%<>%
opérateur de remplacer objet d'entrée pourrait être simplifié pourdf %<>% select(-col.to.drop.1, -col.to.drop.2, ..., -col.to.drop.6)
dplyr
, il pourrait être plus facile de les regrouper et de mettre un seul moins:df.cut <- df %>% select(-c(col.to.drop.1, col.to.drop.2, ..., col.to.drop.n))
Je continue à penser que il doit y avoir une meilleure idiome, mais pour la soustraction de colonnes par leur nom, j'ai tendance à faire ce qui suit:
df[,-match(c("e","f"),names(df))]
-
?Il y a une fonction appelée
dropNamed()
de Bernd Bischl deBBmisc
package qui fait exactement cela.L'avantage est qu'il évite de répéter le bloc de données de l'argument et est donc adapté pour la tuyauterie dans
magrittr
(tout comme ledplyr
approches):Une autre solution si vous ne souhaitez pas utiliser @hadley est ci-dessus: Si "COLUMN_NAME" est le nom de la colonne que vous voulez supprimer:
COLUMN_NAME
n'est pas dansdf
(vérifiez vous-même:df<-data.frame(a=1,b=2)
). (3)df[,names(df) != "COLUMN_NAME"]
est plus simple et n'en souffrent pas (2)Au-delà de
select(-one_of(drop_col_names))
démontré dans les réponses précédentes, il ya un couple d'autresdplyr
options pour la suppression de colonnes à l'aide deselect()
qui n'impliquent pas la définition de tous les noms de colonne (à l'aide de la dplyr starwars données de l'échantillon pour un peu de variété dans les noms de colonne):Fournir les bloc de données et une chaîne de séparés par des virgules de noms à supprimer:
Utilisation:
Trouver l'index de colonnes que vous voulez déposer à l'aide de
which
. Donner à ces indices d'un signe négatif (*-1
). Puis sous-ensemble sur ces valeurs, ce qui permettra de les retirer de la dataframe. C'est un exemple.