我在rlang::call_args中使用dplyr::mutate时出错了。我已经找到了不使用dplyr::mutate的解决办法。我在这里的目的是找出错误的实际原因,并学习使用rlang和dplyr的正确方法。
我有一个数据帧,其中有一个列存储函数调用,如
df <- tibble::tibble(
`call` = c(expr(f1(a=1, b=2)), expr(f2(x=5,y=6)), expr(f3(m=9, n=10)))
)
# > df
# # A tibble: 3 x 1
# call
# <list>
# 1 <language>
# 2 <language>
# 3 <language>我想用rlang::call_args为参数列表创建一个新列。预期的输出应该如下所示
# # A tibble: 3 x 2
# call args
# <list> <list>
# 1 <language> <named list [2]>
# 2 <language> <named list [2]>
# 3 <language> <named list [2]>将包含函数参数的命名列表作为args列中的每一行:
> expected_output$args[[1]]
# $a
# [1] 1
# $b
# [1] 2 和
> expected_output$args[[2]]
# $x
# [1] 5
# $y
# [1] 6 诸若此类。
当我尝试使用rlang::call_args和dplyr::mutate时,我发现了错误,告诉我输入不是引用的调用:
> df %>% mutate(args = rlang::call_args(call))
Error: Problem with `mutate()` input `args`.
x `call` must be a quoted call
ℹ Input `args` is `rlang::call_args(call)`.
Run `rlang::last_error()` to see where the error occurred.
> rlang::last_error()
<error/dplyr:::mutate_error>
Problem with `mutate()` input `args`.
x `call` must be a quoted call
ℹ Input `args` is `rlang::call_args(call)`.
Backtrace:
Run `rlang::last_trace()` to see the full context.
> rlang::last_trace()
<error/dplyr:::mutate_error>
Problem with `mutate()` input `args`.
x `call` must be a quoted call
ℹ Input `args` is `rlang::call_args(call)`.
Backtrace:
█
1. ├─df %>% mutate(args = rlang::call_args(call))
2. ├─dplyr::mutate(., args = rlang::call_args(call))
3. ├─dplyr:::mutate.data.frame(., args = rlang::call_args(call))
4. │ └─dplyr:::mutate_cols(.data, ...)
5. │ ├─base::withCallingHandlers(...)
6. │ └─mask$eval_all_mutate(dots[[i]])
7. ├─rlang::call_args(call)
8. │ └─rlang:::abort_call_input_type("call")
9. │ └─rlang::abort(sprintf("`%s` must be a quoted call", arg))
10. │ └─rlang:::signal_abort(cnd)
11. │ └─base::signalCondition(cnd)
12. └─(function (e) ...我已经检查了df$call的元素,并确认所有元素都是调用对象。
> all(sapply(df$call, rlang::is_call))
# [1] TRUE我不知道x 'call' must be a quoted call在错误消息中到底是什么意思。我认为dplyr::mutate中的函数参数应该自动作为引用表达式来处理,因为我们可以这样做
dplyr::mutate(df, NEWVAR = tolower(OLDVAR))没有错误的对象'OLDVAR‘没有找到。
我已经找到了一个解决办法:
> tibble::as_tibble(list(call = df$call, args = lapply(df$call, call_args)))
# # A tibble: 3 x 2
# call args
# <list> <list>
# 1 <language> <named list [2]>
# 2 <language> <named list [2]>
# 3 <language> <named list [2]>使用这个线程,我并不是在寻找解决这个特定问题的另一种方法,而是要清楚地理解dplyr::mutate的错误,并学习使用dplyr和rlang函数的正确方法。
发布于 2021-10-27 16:58:27
有两个潜在的问题,不特定于rlang
call_args()不是向量化的(如另一个注释中提到的),这意味着它一次只能处理一个调用,而不能处理一个列表或一个调用向量。编写df %>% mutate(args = call_args(call))等同于df$args = call_args(df$call),其中df$call是由3个表达式组成的向量。尝试一下,您就会得到您描述的相同的错误。可能的解决方案是使用dplyr::rowwise()call_args()返回一个列表,可能长度大于1。要在行级变异中使用它,需要将它的输出封装在一个显式的list()中。否则,dplyr会抱怨您试图将2个值赋给1行数据帧中的一个变量.。
解决方案:
df = df %>% rowwise() %>% mutate(args = list(rlang::call_args(call))) %>% ungroup()
df$args注意:您提供的lapply()方法也可以通过变异完成,而不需要行。不过,也许不那么无聊了?
df = df %>% mutate(args = lapply(call, rlang::call_args))
df$argshttps://stackoverflow.com/questions/69737200
复制相似问题