web-dev-qa-db-fra.com

Quel est le moyen le plus efficace de sélectionner un ensemble de noms de variables à partir d'un R data.frame?

Le problème:

J'ai souvent besoin de sélectionner un ensemble de variables dans data.frame dans R. . Mes recherches portent sur les sciences sociales et du comportement, et il est assez courant d'avoir un data.frame contenant plusieurs centaines de variables (par exemple, Vous obtiendrez des informations au niveau des éléments pour une série de questions d’enquête, d’éléments démographiques, de mesures de performance, etc., etc.

Dans le cadre d’analyses, je souhaite souvent sélectionner un sous-ensemble de variables .Par exemple, j’aimerais obtenir:

  • statistiques descriptives pour un ensemble de variables
  • matrice de corrélation sur un ensemble de variables
  • analyse factorielle sur un ensemble de variables
  • prédicteurs dans un modèle linéaire

Maintenant, je sais qu'il existe de nombreuses façons d'écrire le code pour sélectionner un sous-ensemble de variables . Quick-r a une vue d'ensemble de Nice sur les méthodes courantes d'extraction de sous-ensembles de variables d'un nom data.frame .

par exemple., 

myvars <- c("v1", "v2", "v3")
newdata <- mydata[myvars]

Cependant, l'efficacité de ce processus m'intéresse, en particulier lorsque vous devez extraire une vingtaine de variables à partir d'un nom de données.fr. La convention de dénomination des variables n'est souvent pas intuitive, en particulier lorsque vous avez hérité d'un jeu de données de quelqu'un d'autre, vous risquez donc de vous demander si la variable Gender, gender, sex, GENDER, gender1, etc. .. est multipliée par 20 variables à extraire et la tâche de mémoriser les noms de variables devient plus compliquée qu'elle ne le devrait.

Exemple concret

Pour concrétiser la discussion suivante, je vais utiliser bfi data.frame dans le package psych.

library(psych)
data(bfi)
df <- bfi
head(df, 1)
      A1 A2 A3 A4 A5 C1 C2 C3 C4 C5 E1 E2 E3 E4 E5 N1 N2 N3 N4 N5 O1 O2 O3 O4
61617  2  4  3  4  4  2  3  3  4  4  3  3  3  4  4  3  4  2  2  3  3  6  3  4
      O5 gender education age
61617  3      1        NA  16
  • Comment puis-je sélectionner efficacement un ensemble arbitraire de variables, pour lesquelles je choisirai A1, A2, A3, A5, C2, C3, C5, E2, E3, gender, education, age?

Ma stratégie actuelle

J’utilise actuellement diverses stratégies… .. Bien sûr, je peux parfois exploiter des éléments tels que la position numérique des variables ou la convention de dénomination et utiliser soit grep pour sélectionner ou paste pour construire. Mais parfois, j'ai besoin d'une solution plus générale. J'ai utilisé ce qui suit pendant tout ce temps:

1. noms (df)

Au début, j’appelais names(df), copiais les noms de variables cités, puis l’éditais jusqu’à ce que j’ai ce que je veux.

2. Utiliser une base de données

Parfois, j'ai un data.frame distinct qui stocke chaque variable sous forme de ligne, avec des colonnes pour les noms de variable, des étiquettes de variable et une colonne indiquant si la variable doit être conservée pour une analyse particulière. Je peux alors filtrer sur cette variable include et extraire un vecteur de noms de variables. Je trouve cela particulièrement utile lorsque je développe un test psychologique et que, pour diverses itérations, je souhaite inclure ou exclure certains éléments.

3. dput (noms (df))

Comme Hadley Wickham m'a déjà fait remarquerdput est une bonne option; Par exemple, dput(names(df)) est préférable à names(df) en ce sens qu'il génère une liste qui est déjà au format c("var1", "var2", ...):

dput(names(df))
c("A1", "A2", "A3", "A4", "A5", "C1", "C2", "C3", "C4", "C5", 
"E1", "E2", "E3", "E4", "E5", "N1", "N2", "N3", "N4", "N5", "O1", 
"O2", "O3", "O4", "O5", "gender", "education", "age")

Cela peut ensuite être copié dans le script et édité.

Mais peut-il être plus efficace

Je suppose que dput est une très bonne stratégie de sélection variable. L’efficacité du processus dépend en grande partie de votre aptitude à copier le texte dans votre script, puis à modifier la liste des noms jusqu’à ce que vous souhaitiez.

Cependant, je me souviens encore de l'efficacité des systèmes de sélection de variables basés sur l'interface graphique . Par exemple, dans SPSS, lorsque vous interagissez avec une boîte de dialogue, vous pouvez pointer et cliquer avec la souris sur les variables souhaitées à partir du jeu de données. Vous pouvez déplacer en maintenant la touche Maj enfoncée pour sélectionner une plage de variables. Maintenez la touche Maj enfoncée et appuyez sur la touche Bas pour sélectionner une ou plusieurs variables, etc. Ensuite, vous pouvez appuyer sur Paste et la commande contenant les noms de variables extraites est collée dans votre éditeur de script.

Donc, enfin la question centrale

  • Existe-t-il un dispositif graphique simple et sans fioritures qui permet la sélection de variables à partir d'un nom de données (par exemple, quelque chose comme guiselect(df) ouvre une fenêtre graphique pour la sélection de variables) et renvoie un vecteur de noms de variables sélectionnés c("var1", "var2", ...)?
  • dput est-il la meilleure option générale pour sélectionner un ensemble de noms de variables dans R? Ou y a-t-il un meilleur moyen?

Mise à jour (avril 2017): J'ai publié ma propre compréhension d'une bonne stratégie ci-dessous .

37
Jeromy Anglim

Personnellement, je suis un fan de myvars <- c(...) puis d’utiliser mydf[,myvars] à partir de là dans.

Cependant, cela nécessite toujours que vous entriez les noms de variables initiaux (même une seule fois), et pour autant que je lise votre question, c’est ce «choix de noms de variables» initial qui vous intéresse.

S’agissant d’un simple périphérique graphique GUI, la fonction menu a été récemment présentée. Il s’agit d’un simple périphérique graphique GUI permettant de sélectionner un objet dans une liste de choix. Essayez menu(names(df),graphics=TRUE) pour voir ce que je veux dire (renvoie le numéro de colonne). Cela donne même une interface texte agréable si pour une raison quelconque votre système ne peut pas faire les graphiques (essayez avec graphics=FALSE pour voir ce que je veux dire).

Cependant, ceci est d'une utilité limitée pour vous, car vous ne pouvez sélectionner qu'un seul nom de colonne . Pour sélectionner multiple , vous pouvez utiliser select.list (mentionné dans ?menu en tant qu'alternative pour effectuer plusieurs sélections):

# example with iris data (I don't have 'psych' package):
vars <- select.list(names(iris),multiple=TRUE,
                    title='select your variable names',
                    graphics=TRUE)

Cela prend également une option graphics=TRUE (un simple clic sur tous les éléments que vous souhaitez sélectionner). Il retourne les noms des variables. 

23
mathematical.coffee

Vous pouvez utiliser select.list(), comme ceci:

DF <- data.frame(replicate(26,list(rnorm(5))))
names(DF) <- LETTERS
subDF <- DF[select.list(names(DF), multiple=TRUE)]
10
Josh O'Brien

J'utilise la stratégie suivante pour effectuer une sélection variable dans R efficient.

Utiliser les métadonnées pour stocker les noms de variables

J'ai des cadres de données avec une ligne par variable pour certains ensembles de variables. Par exemple, je pourrais avoir un test de personnalité de 100 éléments. Les métadonnées incluent le nom de la variable dans R ainsi que toutes les informations de scoring (par exemple, si l'élément est inversé, etc.). Je peux ensuite extraire les noms de variable pour les éléments et les noms d'échelle à partir de ces métadonnées. 

Stocker des ensembles de variables dans une liste nommée

Dans chaque projet, j'ai une liste appelée v qui stocke des ensembles nommés de variables . Puis, dans toute analyse nécessitant un ensemble de variables, je peux simplement me référer à la liste nommée. Cela rend également le code plus fiable, car si les noms de variables changent, toutes vos analyses de contingence sont modifiées. C'est également bon pour créer une cohérence dans la façon dont les variables sont ordonnées.

Voici un exemple simple:

v <- list()
v$neo_items <- meta.neo$id
v$ds14_items <- meta.ds14$id
v$core_items <- c(v$neo_items, v$ds14_items)       

v$typed_scales <- c("na", "si")
v$typed_all <- c("typed_continuous_sum", "na", "si")
v$neo_facets <- sort(unique(meta.neo$facet))
v$neo_factors <- c("agreeableness", "conscientiousness", 
                   "extraversion", "neuroticism", "openness")
v$outcomes_scales <- c("healthbehavior", "socialsupport", 
                "physical_symptoms", "psychological_symptoms")

Quelques exemples peuvent être tirés de l'exemple ci-dessus:

  • Souvent, les listes de variables sont générées à partir de métadonnées que j'ai stockées séparément. Ainsi, par exemple, j'ai les noms de variable pour les 240 itms du test de personnalité neo stockés dans meta.neo$id
  • Dans certains cas, les noms de variables peuvent être dérivés de métadonnées. Par exemple, l'une des colonnes de mes métadonnées pour un test de personnalité indique à quelle échelle appartient l'élément et les noms des variables sont dérivés de cette colonne en prenant la valeur unique de cette colonne.
  • Dans certains cas, les ensembles variables sont la combinaison d’ensembles plus petits. Ainsi, par exemple, vous pouvez avoir un ensemble de prédicteurs, un ensemble de résultats et un ensemble combinant prédicteurs et résultats. La division en prédicteurs et résultats peut être utile pour certains modèles de régression et l'ensemble combiné peut être utile pour une matrice de corrélation ou une analyse factorielle.
  • Pour plus de listes de variables ad hoc, j'utilise toujours dput(names(df), où df est mon data.frame pour générer le vecteur de noms de caractères qui est ensuite stocké dans une liste de variables. 
  • Ces listes de variables sont généralement placées après le chargement de vos données, mais avant de les transférer. De cette façon, ils peuvent être utilisés pour la préparation des données et ils sont certainement disponibles lorsque vous démarrez des analyses (par exemple, des modèles prédictifs, des corrélations, des statistiques descriptives, etc.).
  • La beauté des listes de variables est que vous pouvez facilement utiliser la copie automatique dans RStudio. Donc, vous n'avez pas besoin de vous souvenir des noms de variables ni même des noms des listes de variables. Vous tapez simplement v$ et appuyez sur Tab ou v$ et une partie du nom de la liste.

Utiliser les listes de variables

L'utilisation de listes de variables est assez simple, mais certaines fonctions de R spécifient les noms de variables différemment.

Le scénario simple et standard consiste à fournir la liste des noms de variables au sous-ensemble data.frame. Par exemple,

cor(data[,v$mylist])
cor(data[,v$predictors], data[,v$outcomes])

C'est un peu plus compliqué pour les fonctions qui nécessitent des formules. Vous devrez peut-être écrire une fonction. Par exemple:

v <- list()
v$predictors <- c("cyl", "disp")
f <- as.formula(paste("mpg ~", paste(v$predictors, collapse = " + ")))
lm(f, mtcars)

Vous pouvez également utiliser des listes de variables dans des fonctions telles que sapply et lapply (et vraisemblablement les équivalents tidyverse). Par exemple,

Créez un tableau de statistiques descriptives avec:

sapply(mydata[, v$outcomes], function(X) c(mean = mean(X), sd = sd(X)))

dput est toujours utile

Pour les variables ad hoc ou même lorsque vous écrivez simplement le code pour créer une liste de variables, dput est toujours très utile.

Le code standard est dput(names(df)), où df est votre nom de données.fr. Donc par exemple:

 dput(names(mtcars))

Produit

 c("mpg", "cyl", "disp", "hp", "drat", "wt", "qsec", "vs", "am", 
 "gear", "carb")

Vous pouvez ensuite éditer cette chaîne pour extraire les variables dont vous avez besoin ..__ Ceci a l'avantage supplémentaire de réduire les erreurs de frappe dans votre code. Et c'est un point très important. Vous ne voulez pas passer beaucoup de temps à essayer de déboguer du code résultant simplement d'une faute de frappe. De plus, le message d'erreur Rs lors de la saisie d'un nom de variable est terrible. Il dit simplement "colonnes indéfinies sélectionnées". Cela ne vous dit pas quels noms de variables étaient faux.

Si vous avez un grand nombre de variables, vous pouvez également utiliser une gamme de fonctions de recherche de chaînes pour extraire un sous-ensemble des noms de variables:

Par exemple

> library(psych)
> dput(names(bfi)) #all items
c("A1", "A2", "A3", "A4", "A5", "C1", "C2", "C3", "C4", "C5", 
"E1", "E2", "E3", "E4", "E5", "N1", "N2", "N3", "N4", "N5", "O1", 
"O2", "O3", "O4", "O5", "gender", "education", "age")
> dput(grep("^..$", names(bfi), value = TRUE)) # two letter variable names
c("A1", "A2", "A3", "A4", "A5", "C1", "C2", "C3", "C4", "C5", 
"E1", "E2", "E3", "E4", "E5", "N1", "N2", "N3", "N4", "N5", "O1", 
"O2", "O3", "O4", "O5")
> dput(grep("^E.$", names(bfi), value = TRUE)) # E items
c("E1", "E2", "E3", "E4", "E5")
> dput(grep(".5$", names(bfi), value = TRUE)) # 5th items
c("A5", "C5", "E5", "N5", "O5")

Nettoyer les noms de variables existants et utiliser une convention de dénomination

Lorsque j'obtiens un fichier de données de quelqu'un d'autre, les noms de variable manquent souvent de conventions ou utilisent des conventions qui rendent l'utilisation des variables moins utile en R. Quelques règles que j'utilise:

  • faire en sorte que toutes les variables soient en minuscule (il est ennuyeux de penser aux variables minuscules et majuscules)
  • rendre les noms de variable intrinsèquement significatifs (certains logiciels utilisent des étiquettes de variable pour stocker des données significatives; R n'utilise pas vraiment d'étiquette)
  • Conservez les variables à une longueur appropriée (c'est-à-dire pas trop longue). Jusqu'à 10 caractères, c'est bien. Plus de 20 sont énervants.

Toutes ces étapes facilitent généralement la sélection de variables car il y a moins d'incohérences à retenir.Utiliser la complétion par tabulation pour les noms de variables individuelles.

Pour les variables individuelles, j'utilise généralement l'auto-complétion à partir du bloc de données. Par exemple, df$ et appuyez sur la touche de tabulation.

J'essaie d'utiliser un style de codage qui me permet d'utiliser l'auto-complétion autant que possible. Je n'aime pas les fonctions pour lesquelles je dois connaître le nom de la variable sans utiliser l'auto-complétion. Par exemple, lorsqu’on sous-définit un data.frame, je préfère 

df[ df$sample == "control", ]

subset(df, sample == "control")

because I can autocomplete the variable name "sample" in the top example, but not in the second.

5
Jeromy Anglim

Si vous voulez une méthode qui ignore le cas des variables et peut-être sélectionne les variables sur la base de leurs "tiges", utilisez le modèle de regex approprié et ignore.case- = TRUE et value = TRUE avec grep:

 dfrm <- data.frame(var1=1, var2=2, var3=3, THIS=4, Dont=5, NOTthis=6, WANTthis=7)
unlist(sapply( c("Want", "these", "var"),
   function(x) grep(paste("^", x,sep=""), names(dfrm), ignore.case=TRUE, value=TRUE) ))
#----------------
      Want       var1       var2       var3   # Names of the vector
"WANTthis"     "var1"     "var2"     "var3"   # Values matched
> dfrm[desired]
  WANTthis var1 var2 var3
1        7    1    2    3
3
42-

Voulez-vous dire select?

sub_df = subset(df, select=c("v1","v2","v3"))
0
user702432