我正在尝试编写几个嵌入式函数,这些函数最终会过滤id_type
中的一列(filter_data()
),该列由id_types
中的load_data()
定义})。基于新的dplyr programming vignette,我正在尝试使用enquo
来运行我的代码,但我收到的错误是我不知道如何处理。
实际代码更复杂(实际上需要不同的函数),但这是我可以用来复制错误的最简单的代码:
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()
引发以下错误:
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)
我想要的输出:我希望代码遍历所有id_types
,过滤df
id_a == 1
,id_b == 1
或id_c == 1
(行)原始df上的1,2和4,并将它们绑定在一个新的数据框中。
如何在不删除嵌套函数的情况下使此代码正常工作?
谢谢。
答案 0 :(得分:0)
我仍然不明白为什么原始代码不起作用,但我确实找到了另一种解决方案。
替换它:
quo_id_type <- enquo(id_type)
filter(df, !!quo_id_type == 1)
有了这个:
filter_at(df, vars(id_type), all_vars(. == 1))
答案 1 :(得分:0)
如果您需要.data
功能,可以切换到此功能,这样更容易也更明显(df
是指您filter
传入[[
id_type
,当id_type
是字符串时,filter_data <- function(df, id_type) {
filter(df, .data[[id_type]] == 1)
}
选择filter_data
列:
filter_at(data, vars(id_types), any_vars(. == 1))
如果您完全放弃bind_rows
功能,可以使用:
pmap
(同时放弃all_vars
和any_vars
来电。请注意,您需要将id_types
更改为filter
,因为您正在同时评估> 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>
中的所有变量。
在此示例中,您传递给FALSE
的参数是一个字符串(即&#34; id_a&#34;),但即使这样也不会起作用:
"id_a"
过滤条件的计算结果为1
,因为字符串tibble
不等于整数id_types[[1]]
,因此没有行满足条件,因此返回空{{1} }。
您传递给该函数的参数实际上是enquo()
,而不是&#34; id_a&#34;,因此您需要f <- function(id_type) enquo(id_type)
f(id_types[[1]])
f("id_a")
。您可以通过尝试来看到:
<quosure: global>
~id_types[[1]]
<quosure: empty>
~"id_a"
返回:
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)
}
更改为此来修复此问题(并打印其他问题)(但我不建议实际执行此操作):
textField.isUserInteractionEnabled = false