我如何在 `mutate_at` 中应用一个函数来按行对其他列中的值设置条件?

How do I apply a function within `mutate_at` that conditions rowwise on values in other columns?

我有一个数据框,我想在其中转换一组列的值,条件是同一行中另一组列中的值。我尝试在 tidyverse 中结合 rowwisemutate_at 执行此操作,但未能成功。这是一个可重现的例子。

library(dplyr)

set.seed(20912)
dat <- data.frame(cat1 = sample(LETTERS[1:2], 10, replace = TRUE), cat2 = sample(LETTERS[1:2], 10, replace = TRUE), id = 3, sim_1 = rnorm(10), sim_2 = rnorm(10), stringsAsFactors = FALSE)

> dat
   cat1 cat2 id      sim_1       sim_2
1     A    A  3 -0.1054062 -0.47563580
2     B    A  3 -1.7198921  0.76713640
3     A    B  3 -0.5946627 -0.33958464
4     B    B  3 -1.6547488 -0.13026564
5     B    B  3 -0.3779149  1.29590315
6     B    B  3  0.6271939  0.08707965
7     B    B  3  1.6376711  1.02151753
8     A    B  3  1.7675520  1.66983954
9     B    A  3 -0.3284081 -1.28175621
10    B    B  3  0.8431148 -0.15415091

在 table 中,我想转换以 "sim_" 开头的所有列的值,条件是 cat1cat2 的值。比如说,我想用 NA 替换所有 "sim_*" 列中的值,但只替换 cat1 == cat2 所在的行中的值。所以我的预期结果是:

   cat1 cat2 id      sim_1      sim_2
1     A    A  3         NA         NA
2     B    A  3 -1.7198921  0.7671364
3     A    B  3 -0.5946627 -0.3395846
4     B    B  3         NA         NA
5     B    B  3         NA         NA
6     B    B  3         NA         NA
7     B    B  3         NA         NA
8     A    B  3  1.7675520  1.6698395
9     B    A  3 -0.3284081 -1.2817562
10    B    B  3         NA         NA

我尝试了一些关于 rowwisemutate_at 主题的变体,但没有成功。例如:

> dat %>% rowwise() %>% mutate_at(vars(starts_with("sim_")), function(x) { ifelse(cat1 == cat2, NA, x) })
Error in ifelse(cat1 == cat2, x, 0) : object 'cat1' not found

我错过了什么?我意识到,如果我先将数据从宽改造成长,这会更容易,但我希望了解一些有关 tidyverse 函数或语法的知识,并找到一种无需重塑数据即可完成此操作的方法。

我们可以使用replaceifelse/replace进行向量化,这样可以避免rowwise

library(dplyr)
dat %>%
   mutate_at(vars(starts_with('sim')), ~ replace(., cat1 == cat2, NA_real_))

或者因为这些是数字列,可以直接做转换

dat %>% 
   mutate_at(vars(starts_with('sim')),  ~.* NA^(cat1 == cat2))