首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >rlang: call_args在dplyr::突变中

rlang: call_args在dplyr::突变中
EN

Stack Overflow用户
提问于 2021-10-27 10:44:31
回答 1查看 365关注 0票数 1

我在rlang::call_args中使用dplyr::mutate时出错了。我已经找到了不使用dplyr::mutate的解决办法。我在这里的目的是找出错误的实际原因,并学习使用rlangdplyr的正确方法。

我有一个数据帧,其中有一个列存储函数调用,如

代码语言:javascript
复制
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为参数列表创建一个新列。预期的输出应该如下所示

代码语言:javascript
复制
# # 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列中的每一行:

代码语言:javascript
复制
> expected_output$args[[1]]
# $a
# [1] 1

# $b
# [1] 2 

代码语言:javascript
复制
> expected_output$args[[2]]
# $x
# [1] 5

# $y
# [1] 6 

诸若此类。

当我尝试使用rlang::call_argsdplyr::mutate时,我发现了错误,告诉我输入不是引用的调用:

代码语言:javascript
复制
> 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的元素,并确认所有元素都是调用对象。

代码语言:javascript
复制
> all(sapply(df$call, rlang::is_call))
# [1] TRUE

我不知道x 'call' must be a quoted call在错误消息中到底是什么意思。我认为dplyr::mutate中的函数参数应该自动作为引用表达式来处理,因为我们可以这样做

代码语言:javascript
复制
dplyr::mutate(df, NEWVAR = tolower(OLDVAR))

没有错误的对象'OLDVAR‘没有找到。

我已经找到了一个解决办法:

代码语言:javascript
复制
> 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的错误,并学习使用dplyrrlang函数的正确方法。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2021-10-27 16:58:27

有两个潜在的问题,不特定于rlang

  1. call_args()不是向量化的(如另一个注释中提到的),这意味着它一次只能处理一个调用,而不能处理一个列表或一个调用向量。编写df %>% mutate(args = call_args(call))等同于df$args = call_args(df$call),其中df$call是由3个表达式组成的向量。尝试一下,您就会得到您描述的相同的错误。可能的解决方案是使用dplyr::rowwise()

  1. call_args()返回一个列表,可能长度大于1。要在行级变异中使用它,需要将它的输出封装在一个显式的list()中。否则,dplyr会抱怨您试图将2个值赋给1行数据帧中的一个变量.

解决方案:

代码语言:javascript
复制
df = df %>% rowwise() %>% mutate(args = list(rlang::call_args(call))) %>% ungroup()
df$args

注意:您提供的lapply()方法也可以通过变异完成,而不需要行。不过,也许不那么无聊了?

代码语言:javascript
复制
df = df %>% mutate(args = lapply(call, rlang::call_args))
df$args
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/69737200

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档