Comment faire pour supprimer des colonnes par leur nom dans un bloc de données
J'ai un grand ensemble de données et je voudrais lire des colonnes spécifiques ou de chute de tous les autres.
data <- read.dta("file.dta")
J'sélectionnez les colonnes que je ne suis pas intéressé par:
var.out <- names(data)[!names(data) %in% c("iden", "name", "x_serv", "m_serv")]
et que j'aimerais faire quelque chose comme:
for(i in 1:length(var.out)) {
paste("data$", var.out[i], sep="") <- NULL
}
à abandonner toutes les autres colonnes. Est-ce la solution optimale?
- dormir sur le problème, je pensais que
subset(data, select=c(...))
aide dans mon cas de l'abandon de vars. toutefois, la question était surtout sur lepaste("data$",var.out[i],sep="")
le cadre d'accéder aux colonnes d'intérêt à l'intérieur de la boucle. comment puis-je coller ou d'une autre manière de composer un nom de colonne? Merci à tous pour votre attention et votre aide - Double Possible de supprimer des colonnes dans la R bloc de données
Vous devez vous connecter pour publier un commentaire.
Vous devez utiliser de l'indexation ou de la
subset
fonction. Par exemple :Ensuite, vous pouvez utiliser le
which
de la fonction et de la-
opérateur dans la colonne d'indexation :Ou, beaucoup plus simple, utilisez le
select
argument de lasubset
fonction : vous pouvez ensuite utiliser la-
opérateur directement sur un vecteur de noms de colonnes, et vous pouvez omettre les guillemets autour des noms de !Notez que vous pouvez également sélectionner les colonnes que vous voulez, au lieu de les laisser tomber les autres :
select
argument de lasubset
fonction fait le travail parfaitement! Merci de juba!which
n'est pas nécessaire, voir l'Ista de réponse. Mais le sous-ensemble avec-
est sympa! Ne savais pas que!subset
semble bon, mais la façon dont elle silencieusement gouttes de valeurs manquantes semble assez dangereux pour moi.subset
est en effet très pratique, mais n'oubliez pas d'éviter de l'utiliser, sauf si vous utilisez R de manière interactive. Voir l'Avertissement dans la fonction de documentation et ce DONC, la question pour plus d'.which
méthode fonctionne très bien, tandis que d'autres ne produisent que le seul premier col.> subset(testData5, select= -c("myCol")) Error in -c("myCol") : invalid argument to unary operator
?-
?Ne pas utiliser
-which()
pour cela, il est extrêmement dangereux. Considérer:D'utiliser plutôt le sous-ensemble ou la
!
fonction:J'ai appris de cette expérience douloureuse. N'abusez pas des
which()
!setdiff
est également utile:setdiff(names(dat), c("foo", "bar"))
setdiff
proposition par @hadley est très bon pour de longues listes de noms.Première, vous pouvez utiliser l'indexation directe (avec des vecteurs de booléens), au lieu de ré-accéder à des noms de colonne si vous travaillez avec le même bloc de données; il sera plus en sécurité comme l'a souligné l'Ista, et plus rapide à écrire et à exécuter. Donc, ce que vous aurez seulement besoin de:
et puis, il suffit de réaffecter des données:
Deuxième, rapide à écrire, vous pouvez affecter directement la valeur NULL pour les colonnes que vous souhaitez supprimer:
Enfin, vous pouvez utiliser le sous-ensemble(), mais il ne peut pas vraiment être utilisé dans le code (même le fichier d'aide avertit à ce sujet). Plus précisément, un problème pour moi est que si vous voulez utiliser directement le drop fonctionnalité de susbset (), vous devrez l'écrire sans guillemets l'expression correspondant à la colonne des noms:
Comme un bonus, voici le petit benchmark des différentes options, qui montre clairement que le sous-ensemble est le plus lent, et que le premier, redéploiement de la méthode la plus rapide:
Code est ci-dessous :
NULL
, mais pourquoi quand vous mettez plus de deux noms est nécessaire de lui attribuerlist(NULL)
? Je suis seulement curieux de savoir comment il fonctionne, parce que j'ai essayé avec un seul nom, et je n'ai pas besoinlist()
$
ou[[
), à l'aide de<- list(NULL)
va en effet conduire à des résultats faux. Si vous accédez à un sous-ensemble de la dataframe avec une ou plusieurs colonnes,<- list(NULL)
est le chemin à parcourir, même si il n'est pas nécessaire pour une colonne dataframe (parce quedf['myColumns']
obtiendrez coulé à un vecteur si nécessaire).Vous pouvez également essayer les
dplyr
package:dplyr::select(df2, -one_of(c('x','y')))
fonctionnera toujours (avec un avertissement), même si certaines des colonnes n'existent pasVoici une solution rapide pour cela. Disons que vous avez une trame de données X avec trois colonnes A, B et C:
Si je veux supprimer une colonne, disons B, il suffit d'utiliser la commande grep sur colnames pour obtenir l'index de colonne, que vous pouvez ensuite utiliser à omettre la colonne.
Votre nouveau X bloc de données serait la suivante (cette fois sans la colonne B):
La beauté de la commande grep est que vous pouvez spécifier plusieurs colonnes qui correspondent à l'expression régulière. Si j'avais X avec cinq colonnes (A,B,C,D,E):
Sortir les colonnes B et D:
EDIT: compte tenu de la grepl suggestion de Matthieu Lundberg dans les commentaires ci-dessous:
Si j'essaie de supprimer une colonne qui est inexistante,rien ne devrait se passer:
X[,-grep("B",colnames(X))]
sera de retour pas de colonnes dans le cas où aucun nom de colonne contientB
, plutôt que de retourner toutes les colonnes qu'on le souhaiterait. Considérer avecX <- iris
pour un exemple. C'est le problème avec les indices négatifs avec les valeurs calculées. Envisagergrepl
à la place.J'ai essayé de supprimer une colonne, tout à l'aide du package
data.table
et a obtenu un résultat inattendu. Je pense que le suivant peut-être la peine de poster. Juste une petite mise en garde.[ Édité par Matthieu ... ]
Fondamentalement, la syntaxe pour
data.table
n'est PAS exactement la même quedata.frame
. Il y a en fait beaucoup de différences, voir FAQ 1.1 et FAQ 2.17. Vous avez été averti!DT[,var.out := NULL]
supprimer les colonnes que vous souhaitez faire.data.frame
etdata.table
classesVoici une autre solution qui peut être utile à d'autres. Le code ci-dessous sélectionne un petit nombre de lignes et de colonnes à partir d'un grand ensemble de données. Les colonnes sont sélectionnées comme dans l'un de juba réponses, sauf que j'utilise une pâte de fonction pour sélectionner un ensemble de colonnes avec les noms qui sont numérotées dans l'ordre:
J'ai changé le code pour:
De toute façon, juba, la réponse est la meilleure solution à mon problème!
select
argument de lasubset
fonction dans mon code. je voulais juste voir comment j'ai pu accéder à l'arbitraire des colonnes dans une boucle dans le cas où je voulais faire autre chose que juste de laisser tomber la colonne. l'ensemble de données original a environ 1200 vars et je suis seulement intéressé à l'aide de 4 d'entre eux, sans savoir exactement où ils sont.Je ne peux pas répondre à votre question dans les commentaires en raison de la faible score de réputation.
Le code suivant vous donnera une erreur car la pâte fonction retourne une chaîne de caractères
Voici une solution possible:
ou tout simplement faire: