在 R 和 dplyr 中,使用“mutate”和“across”将多个“mutate”调用替换为单个调用

Can*_*ice 2 r dplyr

我们在 R 中有以下数据框

# Create example dataframe
df <- data.frame(gp = c(0, 1, 0, 1), 
                 col1A = c(1, 2, 3, 4), 
                 col1B = c(5, 6, 7, 8), 
                 col2A = c(11, 12, 13, 14), 
                 col2B = c(15, 16, 17, 18),
                 col3A = c(11, 12, 13, 14), 
                 col3B = c(15, 16, 17, 18))
Run Code Online (Sandbox Code Playgroud)

我们希望应用以下逻辑:

df %>%
  dplyr::mutate(col1A = ifelse(gp == 0, col1B, col1A)) %>%
  dplyr::mutate(col2A = ifelse(gp == 0, col2B, col2A)) %>%
  dplyr::mutate(col3A = ifelse(gp == 0, col3B, col3A))

Run Code Online (Sandbox Code Playgroud)

然而,我们希望将 3 个mutate调用替换为 1 个结合了mutateand across(或其他方法)的调用。假设我们在字符串中有这些变量,soaVars = c('col1A', 'col2A', 'col3A')bVars = c('col1B', 'col2B', 'col3B')

这种类型的整合是否可行?我们之前已经一起使用过mutateand across,但是当使用两组变量时,就像我们在这里使用AandB变量一样,这样做似乎更困难......

r2e*_*ans 6

我们可以使用cur_column()和修改它(对于尾部"B")来引用每个变量的两个版本。

df %>%
  mutate(
    across(ends_with("A"),
           ~ if_else(gp == 0, cur_data()[[sub("A$", "B", cur_column())]], .))
  )
#   gp col1A col1B col2A col2B col3A col3B
# 1  0     5     5    15    15    15    15
# 2  1     2     6    12    16    12    16
# 3  0     7     7    17    17    17    17
# 4  1     4     8    14    18    14    18
Run Code Online (Sandbox Code Playgroud)