web-dev-qa-db-fra.com

Les données de sous-ensemble ne doivent contenir que des colonnes dont les noms correspondent à une condition

Existe-t-il un moyen pour moi de sous-définir les données en fonction des noms de colonne commençant par une chaîne particulière? J'ai quelques colonnes qui sont comme ABC_1 ABC_2 ABC_3 et d'autres comme XYZ_1, XYZ_2,XYZ_3, disons.

Comment puis-je sous-définir ma df basée uniquement sur des colonnes contenant les parties de texte ci-dessus (disons, ABC ou XYZ)? Je peux utiliser des index, mais les colonnes sont trop dispersées dans les données et cela devient trop difficile à coder.

De plus, je souhaite inclure uniquement les lignes de chacune de ces colonnes dont la valeur est >0. Par conséquent, si l'une des colonnes 6 ci-dessus comporte un 1 dans la ligne, elle coupe dans mon cadre de données final.

37
kaos1511

Essayez grepl sur les noms de votre data.frame. grepl fait correspondre une expression régulière à une cible et renvoie TRUE si une correspondance est trouvée et FALSE sinon. La fonction est vectorisée afin que vous puissiez passer un vecteur de chaînes à faire correspondre et vous obtiendrez un vecteur de valeurs booléennes.

Exemple

#  Data
df <- data.frame( ABC_1 = runif(3),
            ABC_2 = runif(3),
            XYZ_1 = runif(3),
            XYZ_2 = runif(3) )

#      ABC_1     ABC_2     XYZ_1     XYZ_2
#1 0.3792645 0.3614199 0.9793573 0.7139381
#2 0.1313246 0.9746691 0.7276705 0.0126057
#3 0.7282680 0.6518444 0.9531389 0.9673290

#  Use grepl
df[ , grepl( "ABC" , names( df ) ) ]
#      ABC_1     ABC_2
#1 0.3792645 0.3614199
#2 0.1313246 0.9746691
#3 0.7282680 0.6518444

#  grepl returns logical vector like this which is what we use to subset columns
grepl( "ABC" , names( df ) )
#[1]  TRUE  TRUE FALSE FALSE

Pour répondre à la deuxième partie, je créerais le sous-ensemble data.frame, puis un vecteur qui indexerait les lignes à conserver (un vecteur logique) comme ceci ...

set.seed(1)
df <- data.frame( ABC_1 = sample(0:1,3,repl = TRUE),
            ABC_2 = sample(0:1,3,repl = TRUE),
            XYZ_1 = sample(0:1,3,repl = TRUE),
            XYZ_2 = sample(0:1,3,repl = TRUE) )

# We will want to discard the second row because 'all' ABC values are 0:
#  ABC_1 ABC_2 XYZ_1 XYZ_2
#1     0     1     1     0
#2     0     0     1     0
#3     1     1     1     0


df1 <- df[ , grepl( "ABC" , names( df ) ) ]

ind <- apply( df1 , 1 , function(x) any( x > 0 ) )

df1[ ind , ]
#  ABC_1 ABC_2
#1     0     1
#3     1     1
64
Simon O'Hanlon

Vous pouvez également utiliser select() de starts_with et dplyr comme suit:

df <- df %>% dplyr:: select(starts_with("ABC"))
15
basbabybel

En utilisant dplyr, vous pouvez:

df <- df %>% dplyr:: select(grep("ABC", names(df)), grep("XYZ", names(df)))
5
Ram B

Cela a fonctionné pour moi:

df[,names(df) %in% colnames(df)[grepl(str,colnames(df))]]
2
guero64

Juste au cas où pour __ utilisateurs data.table, ce qui suit fonctionne pour moi: 

df[, grep("ABC", names(df)), with = FALSE]
0
Alex Ho