R dplyr case_when 尝试返回表达式时出错

问题描述 投票:0回答:1

我正在尝试使用

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!

r dplyr expression
1个回答
4
投票

如错误所说

输入`输出`必须是向量,而不是表达式向量。

您需要通过

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)
  )
)
© www.soinside.com 2019 - 2024. All rights reserved.