我正在尝试使用
case_when
在数据框中创建分组,而不是在 dplyr 链中创建多个 if_else
语句。
不幸的是,我在尝试返回表达式时遇到了这个错误(然后使用它们在 ggplot 中显示漂亮的数学表达式)
Error: Problem with `mutate()` input `output`.
x Input `output` must be a vector, not an expression vector.
i Input `output` is `case_when(...)`.
Run `rlang::last_error()` to see where the error occurred.
这是一个MWE:
library(dplyr)
fizzbuzz <- data.frame(input = seq(0, 50))
fizzbuzz %>% mutate(
output = case_when(
input %% 35 == 0 ~ expression(f*b[found]),
input %% 5 == 0 ~ expression(f),
input %% 7 == 0 ~ expression(b),
TRUE ~ expression(0)
)
)
# %>% other dplyr operations then ggplot using `output` as a facet
# Fails with error shown above
input = seq(0, 50)
output <- case_when(
input %% 35 == 0 ~ expression(f*b[found]),
input %% 5 == 0 ~ expression(f),
input %% 7 == 0 ~ expression(b),
TRUE ~ expression(0)
)
# works ok, but is an expression not a vector:
# > output
# expression(f * b[found], 0, 0, 0, 0, f, 0, b, 0, 0, f, 0, 0,
# 0, b, f, 0, 0, 0, 0, f, b, 0, 0, 0, f, 0, 0, b, 0, f, 0,
# 0, 0, 0, f * b[found], 0, 0, 0, 0, f, 0, b, 0, 0, f, 0, 0,
# 0, b, f)
我认为应该有一种方法可以将表达式转换为向量?我不确定为什么
dplyr
不会自动将其转换为矢量并且无法在网上找到任何东西。 TIA!
如错误所说
输入`输出`必须是向量,而不是表达式向量。
您需要通过
as.list()
将表达式向量转换为列表。
library(dplyr)
fizzbuzz <- data.frame(input = seq(0, 50))
fizzbuzz %>% mutate(
output = as.list(case_when(
input %% 35 == 0 ~ expression(f*b[found]),
input %% 5 == 0 ~ expression(f),
input %% 7 == 0 ~ expression(b),
TRUE ~ expression(0)
))
)
# input output
# 1 0 f * b[found]
# 2 1 0
# 3 2 0
# 4 3 0
# 5 4 0
# 6 5 f
# 7 6 0
# 8 7 b
自从
dplyr v1.0.x
的某些版本发布后,case_when
不再接受 RHS 上的表达向量。一种解决方案是将 as.list()
移动到 case_when()
周围 expression()
。另一种更简洁的方法是使用 rlang::exprs()
直接返回表达式列表。
library(rlang)
fizzbuzz %>% mutate(
output = case_when(
input %% 35 == 0 ~ exprs(f*b[found]),
input %% 5 == 0 ~ exprs(f),
input %% 7 == 0 ~ exprs(b),
TRUE ~ exprs(0)
)
)