我想将函数应用于向量。但是,该函数需要一系列参数。因此,我需要将向量“拆分”为不相关的参数。
假设我有一个名为dta的数据框。我想运行一个函数,例如在其列之一上运行平均值,例如 DV。
下图显示了问题所在
call("mean", dta$DV)
Run Code Online (Sandbox Code Playgroud)
回报
mean(c(0.371, -0.860, etc... ))
Run Code Online (Sandbox Code Playgroud)
该列是向量这一事实与函数mean不兼容,该函数需要一系列参数,而不是组合。
如果“mean”被替换为包含字符串的变量,则该解决方案应该有效,例如
fun <- "mean"
call( fun, dta$DV)
Run Code Online (Sandbox Code Playgroud)
R 的功能并不完全一致。例如,min和max接受任意数量的参数,其中在数学计算中考虑所有无法识别的参数。mean不是,它必须将所有数字视为第一个(或命名x=)参数。
min(1,20,0)
# [1] 0
min(c(1,20,0))
# [1] 0
mean(1,20,0) # might not be what one would expect
# [1] 1
mean(c(1,20,0))
# [1] 7
Run Code Online (Sandbox Code Playgroud)
出于好奇,20 和 0 不会被忽略,第一次mean调用被解释为mean(0, trim=20, na.rm=0)(其中na.rm=0与 有效相同na.rm=FALSE)。
你的使用call有点不对劲。从帮助中?call,
call 返回未计算的函数调用
这对你并没有多大帮助。您可能会这样做eval(call(...)),但鉴于下一个功能,这似乎很愚蠢。
使用 ofdo.call更直接一些。我可以将其作为第一个参数:一个函数(匿名或命名)或与函数匹配的字符串。使用其中之一实际上存在速度差异,因此我倾向于character在可能的情况下使用对函数名称的引用。(我不记得量化这一断言的参考文献,如果我很快找到它,我会将其包含在内。)
对于像min上面这样可以接受任意数量参数的函数,可以这样做:
args <- c(1,20,0)
as.list(args)
# [[1]]
# [1] 1
# [[2]]
# [1] 20
# [[3]]
# [1] 0
do.call("min", as.list(args)) # == min(1,20,0)
# [1] 0
list(args)
# [[1]]
# [1] 1 20 0
do.call("min", list(args)) # == min(c(1,20,0))
# [1] 0
Run Code Online (Sandbox Code Playgroud)
但是,对于mean和 类似的情况,您需要强制后一种行为:
do.call("mean", list(args)) # == mean(c(1,20,0))
# [1] 7
Run Code Online (Sandbox Code Playgroud)
为了使用以编程方式定义的参数调用函数,您需要使用do.call.