[英]enquo() error in function: the argument has already been evaluated
I'm trying to write several embedded functions that end up filtering a set of columns ( id_type
in filter_data()
) that is defined by a vector ( id_types
in load_data()
). 我试图写结束滤波的一组列的多个嵌入式功能(
id_type
在filter_data()
其由一个矢量定义( id_types
在load_data()
Based on the new dplyr programming vignette , I'm trying to use enquo
to make my code run, but am getting an error that I don't know how to deal with. 基于新的dplyr编程小插图 ,我试图使用
enquo
来使我的代码运行,但是遇到了一个我不知道如何处理的错误。
The actual code is more complicated (and actually requires the different functions), but this is the simplest code I can use to replicate the error: 实际的代码更加复杂(实际上需要不同的功能),但这是我可以用来复制错误的最简单的代码:
library(dplyr)
library(purrr)
data <- tibble(id_a = c(1,1,2,2,3),
id_b = 991,
id_c = c(45,45,45,1,80),
units_sold = c(21,20,24,4,5))
id_types <- c("id_a", "id_b", "id_c")
load_data <- function(){
bind_rows(pmap(list(list(data),
id_types),
filter_data))
}
filter_data <- function(df, id_type) {
quo_id_type <- enquo(id_type)
filter(df, !!quo_id_type == 1)
}
load_data()
throws the following error: 引发以下错误:
Error in (function (x, strict = TRUE) :
the argument has already been evaluated
Called from: (function (x, strict = TRUE)
{
caller_env <- parent.frame()
if (identical(caller_env, globalenv())) {
stop("must be called in a function")
}
if (missing(x)) {
stop("argument \"x\" is missing")
}
.Call(rlang_capturearg, NULL, NULL, pairlist(caller_env,
strict), get_env())
})(id_type)
My desired output: I want the code to iterate through all the id_types
, filtering df
where either id_a == 1
, id_b == 1
, or id_c == 1
(rows 1, 2, and 4 on the original df), and bind those together in a new data frame. 我想要的输出:我希望代码遍历所有
id_types
,过滤df
,其中id_a == 1
, id_b == 1
或id_c == 1
(原始df上的行1、2和4)并绑定它们一起放在一个新的数据框中。
How can I get this code to work without removing the nested functions? 如何在不删除嵌套函数的情况下使此代码正常工作?
Thank you. 谢谢。
I still don't understand why the original code didn't work, but I did find another solution. 我仍然不明白为什么原始代码不起作用,但是我确实找到了另一个解决方案。
Replace this: 替换为:
quo_id_type <- enquo(id_type)
filter(df, !!quo_id_type == 1)
With this: 有了这个:
filter_at(df, vars(id_type), all_vars(. == 1))
If you need the filter_data
function, you can switch to this, which is a bit easier and more obvious ( .data
refers to your df
you pass into filter
, and [[
selects the id_type
column when id_type
is a string): 如果需要
filter_data
函数,则可以切换filter_data
函数,这会更简单,更明显( .data
指向传递给filter
df
,而[[
是id_type
为字符串时选择id_type
列):
filter_data <- function(df, id_type) {
filter(df, .data[[id_type]] == 1)
}
If you can drop the filter_data
function altogether, you can go with: 如果可以完全删除
filter_data
函数,则可以使用:
filter_at(data, vars(id_types), any_vars(. == 1))
(Also dropping the bind_rows
and pmap
calls). (也删除
bind_rows
和pmap
调用)。 Note that you'll need to change all_vars
to any_vars
, since you're evaluating all of the vars in id_types
at once. 请注意,由于您要一次评估
id_types
中的所有var, id_types
需要将all_vars
更改为any_vars
。
In this example, the argument you pass to filter
is a string (ie, "id_a"), but even this by itself won't work: 在此示例中,您传递给
filter
的参数是一个字符串(即“ id_a”),但即使是这样,它本身也不起作用:
> filter(data, "id_a" == 1)
# A tibble: 0 x 4
# ... with 4 variables: id_a <dbl>, id_b <dbl>, id_c <dbl>,
# units_sold <dbl>
The filter condition evaluates to FALSE
, since the string "id_a"
is not equal to the integer 1
, so no rows satisfy the condition, so it returns an empty tibble
. 过滤条件的计算结果为
FALSE
,因为字符串"id_a"
不等于整数1
,所以没有行满足条件,因此它返回空的tibble
。
The argument you pass to the function is really id_types[[1]]
, not "id_a", so that's what you're enquo()
ing. 您传递给函数的参数实际上是
id_types[[1]]
,而不是“ id_a”,所以这就是您enquo()
。 You can see that by trying: 您可以尝试以下方法来查看:
f <- function(id_type) enquo(id_type)
f(id_types[[1]])
f("id_a")
Which returns: 哪个返回:
<quosure: global>
~id_types[[1]]
<quosure: empty>
~"id_a"
You can fix that (and print the other problem) by changing filter_data
to this (but I wouldn't recommend actually doing this): 您可以通过将
filter_data
更改为此(但我不建议实际这样做)来解决该问题(并打印其他问题):
filter_data <- function(df, id_type) {
id_type <- id_type
quo_id_type <- enquo(id_type)
print(quo(filter(df, !!quo_id_type == 1)))
filter(df, !!quo_id_type == 1)
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.