R 用过滤函数对数据条件进行非标准评价
我试图将R 用过滤函数对数据条件进行非标准评价,r,dplyr,nse,R,Dplyr,Nse,我试图将dplyr::filter()与NSE一起使用,但当筛选的变量是as.Date()时,我无法使其工作 以下是几乎可以工作的功能: foo <- function(d, f, var) { d %>% filter_(paste0(var, ">=", f)) } d <- data.frame(a=1:10, b=1) foo(d, f=5, var="a") # a b # 1 5 1 # 2 6 1 # 3 7 1 # 4 8 1
dplyr::filter()
与NSE一起使用,但当筛选的变量是as.Date()
时,我无法使其工作
以下是几乎可以工作的功能:
foo <- function(d, f, var) {
d %>%
filter_(paste0(var, ">=", f))
}
d <- data.frame(a=1:10, b=1)
foo(d, f=5, var="a")
# a b
# 1 5 1
# 2 6 1
# 3 7 1
# 4 8 1
# 5 9 1
# 6 10 1
我也试过这样做:
foo2 <- function(d, f, var) {
d %>%
filter(!!var >= f)
}
#foo2(d, f=5, var="a")
#foo2(d, f="2019-01-05", var="a")
foo2%
过滤器(!!var>=f)
}
#foo2(d,f=5,var=“a”)
#foo2(d,f=“2019-01-05”,var=“a”)
这两种情况下都不起作用,我想知道为什么
foo2
它不起作用。你不需要代码>(rlang::
)。将var
封装到as.name
(或as.symbol
)中,形成一个符号,然后使用eval()
内部过滤器
在函数环境中评估对象:
library(magrittr)
library(dplyr)
d <- data.frame(a=seq.Date(as.Date("2019-01-01"), length.out = 7, by="day"), b=1)
foo2 <- function(d, f, var) {
sym <- as.name(var)
d %>%
filter(eval(sym) >= f)
}
尝试将var
参数作为字符串传递。在这种情况下,您需要将函数foo
更改为:
foo <- function(d, f, var) {
var <- enquo(var)
d %>%
filter(!!var >= f)
}
foo(d, f=as.Date("2019-01-05"), var=a)
foo=f)
}
foo(d,f=截止日期(“2019-01-05”),var=a)
不要修改您的函数。让我们关注代码
foo(d, f = as.Date("2019-01-05"), var = "a")
如果输入的f
是Date
,则函数中的语句paste0(var,“>=”,f)
将返回
“a>=2019-01-05”
(这意味着a
列大于等于“2019-01-05”
,这是一个字符串,而不是日期,因为粘贴()
的输出总是字符)
上面的语句没有意义,因为无法比较字符串。因此,您需要通过unclass()
或as.numeric()
将输入日期转换为数字,例如
foo(d, f = unclass(as.Date("2019-01-05")), var = "a")
语句将返回“a>=17901”
,这是一个正常的逻辑语句
输出
foo(d, f = unclass(as.Date("2019-01-05")), var = "a")
# a b
# 1 2019-01-05 1
# 2 2019-01-06 1
# 3 2019-01-07 1
请注意,“a>=17901”将成功,因为日期(列a
)可以与数字(17910
)进行比较。因为您将变量名作为字符串传递,所以在函数中需要类似ensym()
的内容。如var=ensym(var)
在filter()
行之前。如果您通过as.Date()
传递f
一个值,那么日期应该是有效的。谢谢,这对foo2
有效,可以作为答案发布吗?
foo(d, f = unclass(as.Date("2019-01-05")), var = "a")
foo(d, f = unclass(as.Date("2019-01-05")), var = "a")
# a b
# 1 2019-01-05 1
# 2 2019-01-06 1
# 3 2019-01-07 1