我可以根据许多其他列使用 mutate() 和 across() 来改变许多列吗?

Can I mutate many columns according to many other columns with mutate() and across()?

我有一个数据集,其中大量列具有 NA 个字符,因为它们依赖于另一个列响应。例如:

    df <- data.frame(X_home = c("Yes", "Yes", "No"), 
                     X_school = c("No", "Yes", "No"), 
                     Y_home = c("A", "B", NA), 
                     Y_school = c(NA, "A", NA))

如果我使用 mutate(),我可以:

df %>% mutate(Y_home = if_else(X_home == "No", "C", Y_home),
              Y_school = if_else(X_school == "No", "C", Y_school))

得到我想要的。但问题是我有很多 X_somethingY_something。所以我想用类似的东西来制作它:

df %>% mutate(across(starts_with("Y_"), ~ if_else(...))

可能吗?

非常感谢。

我们可以get使用str_replace

替换列名(cur_column())子串后对应列的值
library(dplyr)
library(stringr)
df %>%
   mutate(across(starts_with("Y_"),
    ~ case_when(get(str_replace(cur_column(), "Y_", "X_")) == "No" ~
       "C", TRUE ~ .x)))

-输出

 X_home X_school Y_home Y_school
1    Yes       No      A        C
2    Yes      Yes      B        A
3     No       No      C        C

这是一种可能的旋转方法:

我们以长格式识别两个一组以模仿相应的列对。

在这些组中,我们 mutate across schoolhome 和 re-pivot 返回:

library(tidyr)
library(dplyr)

df %>%
  mutate(rn = row_number()) %>%
  pivot_longer(cols = -rn, names_to = c( "grp", '.value'), names_sep = "\_") %>%
  group_by(rn) %>% 
  mutate(across(c(home, school), ~ if_else(is.na(.), "C",.))) %>% 
  pivot_wider(names_from = grp, 
              values_from = c(home, school),
              names_glue = "{grp}_{.value}") %>% 
  ungroup() %>% 
  select(-rn)
 X_home Y_home X_school Y_school
  <chr>  <chr>  <chr>    <chr>   
1 Yes    A      No       C       
2 Yes    B      Yes      A       
3 No     C      No       C