有谁知道为什么dplyr::case_when()
会在以下代码中产生错误?
tibble(tmp1 = sample(c(T, F), size = 32, replace = T),
tmp2 = sample(c(T, F), size = 32, replace = T),
tmp3 = sample(c(T, F), size = 32, replace = T)) %>%
mutate(tmp = apply(cbind(tmp1, tmp2, tmp3), 1, function(x) {
case_when(
all(x == F) ~ "N",
any(x == T) ~ "Y"
)
}))
Error in mutate_impl(.data, dots) :
Evaluation error: object 'x' not found.
我在Ubuntu 16.04上使用R 3.4.3和dplyr 0.7.4。
错误消息非常混乱,因为以下代码工作正常,这表明x
没有丢失:
tibble(tmp1 = sample(c(T, F), size = 32, replace = T),
tmp2 = sample(c(T, F), size = 32, replace = T),
tmp3 = sample(c(T, F), size = 32, replace = T)) %>%
mutate(tmp = apply(cbind(tmp1, tmp2, tmp3), 1, function(x) {
if (all(x == F)) {
"N"
} else if(any(x == T)) {
"Y"
}
}))
仅供参考,以下代码也可正常使用:
cbind(tmp1 = sample(c(T, F), size = 32, replace = T),
tmp2 = sample(c(T, F), size = 32, replace = T),
tmp3 = sample(c(T, F), size = 32, replace = T)) %>%
apply(1, function(x) {
case_when(
all(x == F) ~ "N",
any(x == T) ~ "Y"
)
})
答案 0 :(得分:0)
问题是case_when
不执行逐行操作。但是,我们可以使用rowSums
(进行逐行操作)和case_when
来简化代码。
library(dplyr)
set.seed(151)
tibble(tmp1 = sample(c(T, F), size = 32, replace = T),
tmp2 = sample(c(T, F), size = 32, replace = T),
tmp3 = sample(c(T, F), size = 32, replace = T)) %>%
mutate(tmp = case_when(
rowSums(.) == 0 ~"N",
rowSums(.) > 0 ~"Y"
))
# # A tibble: 32 x 4
# tmp1 tmp2 tmp3 tmp
# <lgl> <lgl> <lgl> <chr>
# 1 TRUE TRUE FALSE Y
# 2 FALSE FALSE TRUE Y
# 3 FALSE FALSE TRUE Y
# 4 FALSE FALSE TRUE Y
# 5 TRUE FALSE FALSE Y
# 6 FALSE FALSE FALSE N
# 7 TRUE FALSE FALSE Y
# 8 FALSE TRUE FALSE Y
# 9 TRUE TRUE FALSE Y
# 10 FALSE FALSE TRUE Y
# # ... with 22 more rows
或者由于只有两个条件,rowSums
和ifelse
应该没问题。
set.seed(151)
tibble(tmp1 = sample(c(T, F), size = 32, replace = T),
tmp2 = sample(c(T, F), size = 32, replace = T),
tmp3 = sample(c(T, F), size = 32, replace = T)) %>%
mutate(tmp = ifelse(rowSums(.) == 0, "N", "Y"))
# # A tibble: 32 x 4
# tmp1 tmp2 tmp3 tmp
# <lgl> <lgl> <lgl> <chr>
# 1 TRUE TRUE FALSE Y
# 2 FALSE FALSE TRUE Y
# 3 FALSE FALSE TRUE Y
# 4 FALSE FALSE TRUE Y
# 5 TRUE FALSE FALSE Y
# 6 FALSE FALSE FALSE N
# 7 TRUE FALSE FALSE Y
# 8 FALSE TRUE FALSE Y
# 9 TRUE TRUE FALSE Y
# 10 FALSE FALSE TRUE Y
# # ... with 22 more rows
答案 1 :(得分:0)
如何使用Reduce
和逻辑OR?
set.seed(151);
tibble(tmp1 = sample(c(T, F), size = 32, replace = T),
tmp2 = sample(c(T, F), size = 32, replace = T),
tmp3 = sample(c(T, F), size = 32, replace = T)) %>%
mutate(tmp = Reduce(`|`, list(tmp1, tmp2, tmp3)))
## A tibble: 32 x 4
# tmp1 tmp2 tmp3 tmp
# <lgl> <lgl> <lgl> <lgl>
# 1 TRUE TRUE FALSE TRUE
# 2 FALSE FALSE TRUE TRUE
# 3 FALSE FALSE TRUE TRUE
# 4 FALSE FALSE TRUE TRUE
# 5 TRUE FALSE FALSE TRUE
# 6 FALSE FALSE FALSE FALSE
# 7 TRUE FALSE FALSE TRUE
# 8 FALSE TRUE FALSE TRUE
# 9 TRUE TRUE FALSE TRUE
#10 FALSE FALSE TRUE TRUE
## ... with 22 more rows
答案 2 :(得分:0)
事实证明,这是一个错误,可能与混合评估者有关:https://github.com/tidyverse/dplyr/issues/3422