考虑以下数据:
library(tidyverse)
df <- data.frame(group = rep(letters[1:3], each = 3),
x = 1:9)
我现在想根据检查所有值是否满足特定阈值来按组重新编码值。
使用下面的代码会导致错误
df |>
mutate(test = if_else(all(x < 4), 0, x), .by = group)
Error in `mutate()`:
ℹ In argument: `test = if_else(all(x < 4), 0, x)`.
ℹ In group 1: `group = "a"`.
Caused by error in `if_else()`:
! `false` must have size 1, not size 3.
Run `rlang::last_trace()` to see where the error occurred.
但是,将条件检查移出 if_else 命令,可以按预期工作。
df |>
mutate(helper = all(x < 4),
test = if_else(helper == TRUE, 0, x), .by = group)
group x helper test
1 a 1 TRUE 0
2 a 2 TRUE 0
3 a 3 TRUE 0
4 b 4 FALSE 4
5 b 5 FALSE 5
6 b 6 FALSE 6
7 c 7 FALSE 7
8 c 8 FALSE 8
9 c 9 FALSE 9
我有一个模糊的想法,即 TRUE 部分只是一个标量 (0),if_else 中的 FALSE 部分代表每组中的所有三行,但想更多地了解这里的问题以及为什么 if_else 不不将较短的标量回收到错误语句的长度。
由于
all(x < 4)
的结果是TRUE
或FALSE
,每组使用一次if
将回收0
或采用向量x
(长度为3)。
df %>%
mutate(test = if(all(x < 4)) 0 else x, .by = group)
group x test
1 a 1 0
2 a 2 0
3 a 3 0
4 b 4 4
5 b 3 3
6 b 6 6
7 c 7 7
8 c 8 8
9 c 9 9
(稍作修改)
df <- structure(list(group = c("a", "a", "a", "b", "b", "b", "c", "c",
"c"), x = c(1, 2, 3, 4, 3, 6, 7, 8, 9)), row.names = c(NA, -9L
), class = "data.frame")