R rlang: call_args 在 dplyr::mutate
R rlang: call_args in dplyr::mutate
我在 dplyr::mutate
中使用 rlang::call_args
时出错。我已经找到了不使用 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
与 [= 一起使用的正确方法23=] 函数。
有两个潜在的问题,不是rlang
特有的:
call_args()
未向量化(如另一条评论中所述),这意味着它一次只能处理一个调用,而不是列表或调用向量。写作 df %>% mutate(args = call_args(call))
等同于 df$args = call_args(df$call)
,其中 df$call
是一个包含 3 个表达式的向量。尝试一下,您会遇到与您描述的相同的错误。可能的解决方案是使用 dplyr::rowwise()
call_args()
returns 一个列表,长度可能 > 1。要在行向变异中使用它,您需要将其输出包装在显式 list()
。否则 dplyr 会抱怨您正在尝试将 2 个值分配给 1 行数据框中的变量。
解决方案:
df = df %>% rowwise() %>% mutate(args = list(rlang::call_args(call))) %>% ungroup()
df$args
注意:您使用 tibble 提出的 lapply()
方法也可以使用 mutate 来完成,而无需按行。不过,也许有点 dplyr-ish?
df = df %>% mutate(args = lapply(call, rlang::call_args))
df$args
我在 dplyr::mutate
中使用 rlang::call_args
时出错。我已经找到了不使用 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
与 [= 一起使用的正确方法23=] 函数。
有两个潜在的问题,不是rlang
特有的:
call_args()
未向量化(如另一条评论中所述),这意味着它一次只能处理一个调用,而不是列表或调用向量。写作df %>% mutate(args = call_args(call))
等同于df$args = call_args(df$call)
,其中df$call
是一个包含 3 个表达式的向量。尝试一下,您会遇到与您描述的相同的错误。可能的解决方案是使用dplyr::rowwise()
call_args()
returns 一个列表,长度可能 > 1。要在行向变异中使用它,您需要将其输出包装在显式list()
。否则 dplyr 会抱怨您正在尝试将 2 个值分配给 1 行数据框中的变量。
解决方案:
df = df %>% rowwise() %>% mutate(args = list(rlang::call_args(call))) %>% ungroup()
df$args
注意:您使用 tibble 提出的 lapply()
方法也可以使用 mutate 来完成,而无需按行。不过,也许有点 dplyr-ish?
df = df %>% mutate(args = lapply(call, rlang::call_args))
df$args