我如何在 `mutate_at` 中应用一个函数来按行对其他列中的值设置条件?
How do I apply a function within `mutate_at` that conditions rowwise on values in other columns?
我有一个数据框,我想在其中转换一组列的值,条件是同一行中另一组列中的值。我尝试在 tidyverse
中结合 rowwise
和 mutate_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_"
开头的所有列的值,条件是 cat1
和 cat2
的值。比如说,我想用 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
我尝试了一些关于 rowwise
和 mutate_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
函数或语法的知识,并找到一种无需重塑数据即可完成此操作的方法。
我们可以使用replace
和ifelse/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))
我有一个数据框,我想在其中转换一组列的值,条件是同一行中另一组列中的值。我尝试在 tidyverse
中结合 rowwise
和 mutate_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_"
开头的所有列的值,条件是 cat1
和 cat2
的值。比如说,我想用 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
我尝试了一些关于 rowwise
和 mutate_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
函数或语法的知识,并找到一种无需重塑数据即可完成此操作的方法。
我们可以使用replace
和ifelse/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))