Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

select column names containing string programmatically

Tags:

select

r

quote

expr

Given a data frame like:

df <- data.frame(z_a = 1:2,
                 z_b = 1:2,
                 y_a = 3:4,
                 y_b = 3:4)

I can select columns names that contain a character with:

library(dplyr)
df %>% select(contains("a"), contains("b"))

  z_a y_a z_b y_b
1   1   3   1   3
2   2   4   2   4

NOTE that the column order has changed. Columns containing a come first before columns containing b

I'd like to select column names that contain characters in a vector and that reorders the columns.

searchfor <- letters[1:2]

Using searchfor, I'd like to make the following expression and use it in a select statement:

E <- quote(contains(searchfor[1]), contains(searchfor[2]))
df %>% select_(E) 
like image 589
CPak Avatar asked Oct 29 '25 16:10

CPak


2 Answers

We can do

df %>% 
   select_at(vars(matches(paste(searchfor, collapse="|")))) %>%
   select(order(sub(".*_", "", names(.))))
like image 129
akrun Avatar answered Oct 31 '25 05:10

akrun


purrr solution:

library(purrr)
ind_lgl <- map(letters[1:2], ~ grepl(.x, names(df), fixed = TRUE)) %>%
  pmap_lgl(`|`)

df[ind_lgl]

With the pipe:

df %>%
  `[`(map(letters[1:2], ~ grepl(.x, names(df), fixed = TRUE)) %>%
        pmap_lgl(`|`))

If you to get the right order:

rank <- map(letters[1:2], ~ grepl(.x, names(df), fixed = TRUE)) %>%
  pmap(c) %>%
  map(which)


ind_chr <- data_frame(colnames = names(df), rank) %>%
  mutate(l = lengths(rank)) %>%
  filter(l > 0) %>%
  mutate(rank = unlist(map(rank, ~ .x[[1]]))) %>%
  arrange(rank) %>%
  pull(colnames)


df[ind_chr]

But it is not pretty...

like image 44
F. Privé Avatar answered Oct 31 '25 05:10

F. Privé