dplyr基于具有不同后缀的其他列进行变异

我有一个类似于这个的数据框:

df <- data.frame(a_1_1 = c(1, 0, 1), a_1_2=c(1,0,0),a_2_1=c(1,0,0), a_2_2=c(1,0 ,1), b=c(2,3,4))

我想通过比较具有相同前缀的列来创建新变量,如下所示:

df <- df %>% mutate(a_1=case_when((a_1_1==1 | a_1_2==1)~"A", TRUE ~ "B")) %>% 
mutate(a_2=case_when((a_2_1==1 | a_2_2==1)~"A", TRUE ~ "B"))

然而,在我的真实数据中,我有许多以“a_*”开头的变量,所以我想创建这些变量,而不是一次对每个变量都做。

回答

一个选项 with acrossby 循环以 'a' 开头的列,后跟 a_和一些数字,然后_$字符串末尾 ( )的数字 1 ,case_when在该列 ( .)上使用,并返回 ( get) 由通过将列名 ( cur_column())更改为str_replace,将新列的后缀指定为_new,然后在下一步中将这些列重命名为rename_with

library(dplyr)
library(stringr)
df %>% 
  mutate(across(matches('^a_d+_1$'), 
   ~ case_when(. == 1| get(str_replace(cur_column(), '_d+$', '_2')) == 1 ~ 'A',
      TRUE ~ 'B'), .names = '{.col}_new')) %>%
  rename_with(~ str_remove(., '_d+_new'), ends_with('new'))

-输出

#  a_1_1 a_1_2 a_2_1 a_2_2 b a_1 a_2
#1     1     1     1     1 2   A   A
#2     0     0     0     0 3   B   B
#3     1     0     0     1 4   A   A

或者另一种选择是使用pivot_longer重新整形为“长”格式,并使其更容易进行比较以创建新列,将其重新整形为宽格式,pivot_wider然后将这些新列绑定到原始数​​据

library(tidyr)
df %>%
  select(-b) %>% 
  mutate(rn = row_number()) %>%
  pivot_longer(cols = -rn, names_to = c('grp', '.value'),
      names_sep = "_(?=d+$)") %>% 
  transmute(rn, grp, val = case_when(`1` == 1|`2` == 1 ~ 'A',
       TRUE ~ 'B')) %>% 
  pivot_wider(names_from = grp, values_from = val) %>% 
  select(-rn) %>% 
  bind_cols(df, .)

base Rsplit.default

df[paste0("a_", 1:2)] <- ifelse(
     sapply(split.default(df[startsWith(names(df), "a_")],  
     sub("_d+$", "", grep("^a_", names(df), value = TRUE))),
      rowSums) > 0, 'A', 'B')

或者使用for循环

nm1 <- unique(sub("_d+$", "", grep('^a_d+', names(df), value = TRUE)))
for(nm in nm1) df[[nm]] <- ifelse(rowSums(df[startsWith(names(df), 
      nm)]) > 0, "A", "B")


以上是dplyr基于具有不同后缀的其他列进行变异的全部内容。
THE END
分享
二维码
< <上一篇
下一篇>>