如果我有一个表达式:
z <- x+y
x
和 y
需要定义,而 z
则不需要。如何只获取 x
和 y
?
missing_values('z<-x+y');
[1] "x" "y"
z
需要被删除,以便向用户建议在计算表达式之前需要定义哪些值。
最佳答案
这是一个可能的解决方案,假设多参数函数从左到右评估其参数。这对于典型的二元运算符来说是正确的,这正是您似乎感兴趣的,但正如我在对 @BenBolker 的答案的评论中指出的那样,这并不普遍正确。
find_unbound <- function(lang) {
stopifnot(is.language(lang), !is.expression(lang))
bound <- character()
unbound <- character()
rec_fun <- function(lang) {
if(is.call(lang)) {
# These are assignment calls; if any symbols are assigned and have
# not already been found in a leaf, they are defined as bound
if((lang[[1]] == as.name("<-") || lang[[1]] == as.name("="))) {
for(i in as.list(lang)[-(1:2)]) Recall(i)
if(is.name(lang[[2]]) && !as.character(lang[[2]]) %in% unbound)
bound <<- c(bound, as.character(lang[[2]]))
} else for(i in as.list(lang)[-1]) Recall(i)
} else if (is.name(lang) && ! as.character(lang) %in% bound)
# this is a leaf; any previously bound symbols are by definition
# unbound
unbound <<- c(unbound, as.character(lang))
}
rec_fun(lang)
unique(unbound)
}
find_unbound
一直递归到表达式的叶子节点,以确定每个符号是否已被绑定(bind)。下面是一些测试来说明:
find_unbound(quote(z <- x + y))
# [1] "x" "y"
find_unbound(quote(z <- x + (y <- 3)))
# [1] "x"
find_unbound(quote(z <- z + 1)) # we even figure out `z` depends on itself, so must be provided
# [1] "z"
find_unbound(quote(z <- x + (x <- 3))) # note `x` is evaluated before `x <- 3`
# [1] "x"
find_unbound(quote(z <- (x <- 3) + x)) # but here `x <- 3` is evaluated before `x`
# character(0)
find_unbound(quote({x <- 3; z <- x + y})) # works with multiple calls
# [1] "y"
find_unbound(quote({z <- x + y; x <- 3})) # order matters, just like in R evaluation
# [1] "x" "y"
关于r - 如何获取在计算 R 表达式之前需要定义的所有变量?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32363338/