Subsetgegevens om alleen kolommen te bevatten waarvan de namen overeenkomen met een voorwaarde

Is er een manier waarop ik gegevens kan subsetten op basis van kolomnamen die beginnen met een bepaalde tekenreeks? Ik heb enkele kolommen die lijken op ABC_1 ABC_2 ABC_3en sommige zoals XYZ_1, XYZ_2,XYZ_3laten we zeggen.

Hoe kan ik mijn dfsubsetten op basis van alleen kolommen die de bovenstaande tekstgedeelten bevatten (laten we zeggen ABCof XYZ)? Ik kan indices gebruiken, maar de kolommen zijn te verspreid in gegevens en het wordt teveel harde codering.

Ik wil ook alleen rijen van elk van deze kolommen opnemen waarvan de waarde >0is, dus als een van de 6kolommen hierboven een 1in de rij, het maakt een snee in mijn laatste dataframe.


Antwoord 1, autoriteit 100%

Probeer greplop de namen van uw data.frame. greplkoppelt een reguliere expressie aan een doel en retourneert TRUEals een overeenkomst wordt gevonden en FALSEanders. De functie is gevectoriseerd, dus je kunt een vector van overeenkomende strings doorgeven en je krijgt een vector van booleaanse waarden terug.

Voorbeeld

#  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

Om het tweede deel te beantwoorden, zou ik de subset data.frame maken en dan een vector maken die de rijen indexeert (een logische vector) zoals deze…

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

Antwoord 2, autoriteit 35%

Je kunt ook starts_withen dplyr‘s select()gebruiken als volgt:

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

Antwoord 3, autoriteit 15%

Voor het geval dat voor gebruikers van data.tablehet volgende voor mij werkt:

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

Antwoord 4, autoriteit 13%

Met dplyr kunt u:

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

Antwoord 5, autoriteit 3%

Dit werkte voor mij:

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

Antwoord 6, autoriteit 2%

De eenvoudigste oplossing, mij gegeven door mijn professor statistiek:

df[,grep(“patroon”, colnames(df))]

Dat is het. Het geeft je geen booleans of zo, het geeft je alleen je dataset die dat patroon volgt.


Antwoord 7

Probeer dit (hier, zoek naar variabelen waarvan de naam ‘datum’ bevat, inclusief alle combinaties van hoofdletters):

df %>% dplyr::select(contains(“date”,ignore.case = TRUE))


Antwoord 8

Voortbouwend op het bovenstaande, denk ik dat dit het meest flexibel is. Houd er rekening mee dat je dplyr moet gebruiken, maar dat is niet erg.

Voordeel: u kunt zoeken naar meer dan “contains“. Hier gebruik ik “starts_with” voor een relatief veel voorkomende string “ST”. Het gebruik van “grep” hier had je gemakkelijk gek kunnen maken; gek, zeg ik!

library(dplyr)
df %>% dplyr::select(starts_with("ST",ignore.case = TRUE))

Other episodes