许多R函数采用可变数量的参数。 sum()
就是一个示例:sum(1, 2)
,sum(1, 2, 3)
和sum(1, 2, 3, 4)
都是有效的命令。
我需要编写以批处理模式运行的脚本。在这些脚本中,我需要将多个参数传递给函数。参数不会从命令行传入。它们必须是变量(不是与变量名对应的字符串)。它们都属于同一个类,它们的名称将以相同的字符开头,但我不知道参数的名称或数量。是否有简洁的方法将变量传递给函数?
这是一个例子:我希望代码产生具有模式^int\\d$
的所有变量的总和。我知道至少有一个这样的变量,但我不知道有多少变量。此代码有效:
# Set up toy data
int1 <- 3
int2 <- 5
# Get the sum
argNames <- ls(pat='^int\\d$')
argNames.list <- as.list(argNames)
argNames.list <- lapply(argNames.list, function (x) get(x))
do.call(sum, argNames.list)
我的反对意见是这段代码有点麻烦。将操作扩展到四行以上会降低清晰度。是否有一种R-idiomatic方法可以用更少的代码行来获得相同的结果?
答案 0 :(得分:5)
这稍微简单一点,将其全部封装在一个函数中并消除lapply
和get
。 ix
保存匹配名称的索引。
# sum those arguments whose names match ^int\\d$
sumint <- function(...) {
arg.names <- as.character(match.call()[-1])
ix <- grep("^int\\d$", arg.names)
do.call("sum", list(...)[ix])
}
# test
a <- b <- 10
int3 <- 30
sumint(a, int3, b, int3, b, pi) # 60
答案 1 :(得分:2)
(编辑以更好地解决问题)
我认为你不能比这更好,这对我来说似乎很小。
int1 <- 3
int2 <- 5
do.call(sum, lapply(ls(pat="^int\\d$"), get))
# [1] 8
## Or use a safer version that will only look for objects located in the
## environment from which it was called.
do.call(sum, lapply(ls(pat="^int\\d$"), get, envir=parent.frame(), inherits=FALSE))