简体   繁体   中英

How to Split all the columns of a dataframe into different groups based on string patterns and apply function to each group of columns?

library(glue)
library(tidyverse)

data = crossing(id = c(1:4),q = letters[1:5], nums = c(1:10))
set.seed(25)
data$val = sample(c(NA,"foo", "bar"), nrow(data), prob = c(0.95,0.02,0.03), replace = T)
data = data %>% mutate(q = glue("{q}{nums}")) %>% 
  select(-nums) %>% 
  pivot_wider(id_cols = id, names_from = q, values_from = val)

#Output Im looking for
data %>% 
  select(id,starts_with("a")) %>% 
  mutate(
    a_none = apply(.[,grep("a", names(.))],  1, function(x) all(is.na(x)))
  )

I want to create similar columns as b_none, c_none and so on. While posting the question I got an idea to run a loop and got the answer. I'll add that as well.

You can use split.default to split dataframe based on similar named columns and use imap from purrr to get logical values for each group.

library(dplyr)
library(purrr)

result <- split.default(data[-1], sub('\\d+', '', names(data)[-1])) %>%
  imap_dfc(~.x %>% transmute(!!paste0(.y, '_none') := rowSums(!is.na(.)) == 0))
result

#  a_none b_none c_none d_none e_none
#  <lgl>  <lgl>  <lgl>  <lgl>  <lgl> 
#1 FALSE  FALSE  TRUE   TRUE   FALSE 
#2 TRUE   TRUE   TRUE   TRUE   TRUE  
#3 FALSE  TRUE   TRUE   TRUE   FALSE 
#4 FALSE  TRUE   TRUE   FALSE  FALSE 

If you want to add this as new columns to your original data you can do:

data <- bind_cols(data, result)

To keep this in base R you can use sapply instead of imap :

sapply(split.default(data[-1], sub('\\d+', '', names(data)[-1])), 
       function(x) rowSums(!is.na(x)) == 0)
for (pattern in letters[1:5]) {
  varname = glue("{pattern}_none")
  data[[varname]] = apply(data[,grep(pattern, names(data))],  1, function(x) all(is.na(x)))
}

This for loop did the job for me. Any better ideas?

I tried inserting output using dput() but failed.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM