将一个向量转换为参数列表

3
我想对一个向量应用一个函数。然而,该函数需要一系列参数。因此,我需要将向量“拆分”为不相关的参数。
假设我有一个名为dta的数据框。我想在其中的一列上运行一个函数,比如说平均值(mean)。
以下是问题所在:
call("mean", dta$DV)

返回值

mean(c(0.371, -0.860, etc... ))

这一列是向量的事实与 mean 函数不兼容,因为该函数期望一个单独的参数序列,而不是一个组合。

如果将 "mean" 替换为包含字符串的变量,则解决方案应该有效,例如:

fun <- "mean"

call( fun, dta$DV)

2
好的,我假设你的意思是“一个函数”,而不是特定的 mean,因为它实际上只需要一个向量,而不是一系列参数。对于 mean,我会使用 do.call("mean", list(dta$DV))。但是如果你有一个相反的函数(需要单个参数),你可以使用 do.call("otherfunc", as.list(dta$DV))。这是你的意思吗? - r2evans
好的,也许我没有理解问题。但是,为什么上面的调用没有返回一个数字? - Denis Cousineau
3
如果您阅读?call,它的说明是“'call'返回一个未求值的函数调用”,其中“未求值”是重点。您可以使用eval(call(...))(它会返回平均值),但是您也可以像我之前评论中所示那样使用do.call(...) - r2evans
@r2evans:如果您把您的评论放到一个答案里,我会验证它。感谢您的反馈。 - Denis Cousineau
1个回答

5

R具有不完全一致的函数。例如,minmax接受任意数量的参数,其中所有未识别的参数都将被考虑在数学计算中。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

对于好奇的人,20和0并没有被忽略,第一个mean调用被解释为mean(0, trim=20, na.rm=0)(其中na.rm=0实际上等同于na.rm=FALSE)。
您对call的使用有些不正确。从?call帮助文件中可以看出:

call返回一个未评估的函数调用

这并不能真正帮到您。您可能会使用eval(call(...)),但考虑到下一个函数,这似乎有些愚蠢。
使用do.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

然而,对于 mean 和类似的函数,你需要强制使用后一种行为:

do.call("mean", list(args)) # == mean(c(1,20,0))
# [1] 7

如果您需要以编程方式定义参数来调用函数,则需要使用do.call


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接