我想编写一个在dplyr
链中使用的函数,以按给定的变量排列分组的数据,然后检查该变量是否严格增加了整数(例如1,2,3,...)。为了澄清,我的意思是每个整数都按顺序排列,而不仅仅是增加整数。所以1,2,4,...应该失败。
最终的想法是这样,看起来像这样,并且如果每个组的x都不是1,2,3,...,则会提供一个错误。
d %>% group_by(group) %>% check(x)
我已经编写了一个SE版本,该版本似乎可以正常工作,如下所示,但仍停留在NSE版本上。
check_ <- function(.data, var) {
checkint <- function(x) { stopifnot(x == seq_along(x)) }
do(.data, {
. <- dplyr::arrange_(., var)
checkint(lazyeval::lazy_eval(var, data=.))
.
})
}
在文档中,看起来我应该使用它lazy
来处理单个变量,但是当我要传递的变量也存在于全局环境中时,这将无法正常工作。
checkX <- function(.data, var) {
check_(.data, lazyeval::lazy(var))
}
d <- expand.grid(group=1:2, x=3:1)
x <- 5 ## put an "x" in the global environment
d %>% group_by(group) %>% checkX(x)
## Error: incorrect size (1), expecting : 3
我确实有一个NSE版本,似乎可以正常使用,但是调用lazy_dots
感觉不对,因为我只想要一个变量。
check <- function(.data, ...) {
check_(.data, lazyeval::lazy_dots(...)[[1]])
}
看起来lazyeval
一直在变化。在最新的小插曲甚至没有引用lazy()
函数。它似乎在范围上存在变量问题(更多内容在底部)。现在,我们的功能受到了鼓舞,尽管它们还没有进入所有的“ tidyverse”中。
看起来您想要的功能是expr_find
。如果我们定义checkX
为
checkX <- function(.data, var) {
check_(.data, lazyeval::expr_find(var))
}
这样就可以了
x <- 5
d %>% group_by(group) %>% checkX(x)
(或至少与lazyeval_0.2.0
和一起使用dplyr_0.5.0
)
但是从旧的小插图回到第一个例子
library(lazyeval)
# `x` does not exist here
f <- function(x = a - b) {
lazy(x)
}
f()
# <lazy>
# expr: a - b
# env: <environment: 0x000000000663d618>
exists("x")
# [1] FALSE
f(x)
# <lazy>
# expr: x
# env: <environment: R_GlobalEnv>
x <- 101
f(x)
# <lazy>
# expr: 101
# env: <environment: R_GlobalEnv>
或另一个更简单的例子
# rm(x)
lazy(x)
# <lazy>
# expr: x
# env: <environment: R_GlobalEnv>
x <- 100
lazy(x)
# <lazy>
# expr: 100
# env: <environment: R_GlobalEnv>
它在某处评估参数x,因此如果它存在于来自其的环境中,则永远不会将其保存在惰性对象中。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句