有没有办法编写一个函数,其中一个参数指示要应用什么函数?
例如,如果我有一个功能:
mf = function(data, option, level)
我想在哪里选择来判断是否计算mean
,median
或sd
数据集?
有没有办法编写一个函数,其中一个参数指示要应用什么函数?
例如,如果我有一个功能:
mf = function(data, option, level)
我想在哪里选择来判断是否计算mean
,median
或sd
数据集?
是的,一种选择是将函数传递给option
. 例如
mf <- function(data, option) {
option <- match.fun(option)
option(data)
}
set.seed(42)
dat <- rnorm(10)
mf(dat, option = mean)
这使:
> set.seed(42)
> dat <- rnorm(10)
> mean(dat)
[1] 0.5472968
> mf(dat, option = mean)
[1] 0.5472968
> sd(dat)
[1] 0.8354488
> mf(dat, option = sd)
[1] 0.8354488
match.fun()
是匹配可用函数的标准 R 方式。在示例中,我传递了函数本身,但match.fun()
允许以其他方式引用函数,例如作为字符串:
> mf(dat, option = "mean")
[1] 0.5472968
match.fun()
返回一个可以用作任何其他函数的函数,因此option()
该函数与传递给参数的函数本质上相同,option
或者是在参数中命名的option
函数。
目前尚不清楚该level
论点应该如何用于我忽略了上面的内容。
我可能应该补充一点,如果您想将任何参数传递给应用函数,那么您将希望...
在函数定义中使用,例如:
mf <- function(data, option, ...) {
option <- match.fun(option)
option(data, ...)
}
因此我们可以做这样的事情
set.seed(42)
dat2 <- rnorm(10)
dat2[4] <- NA
mean(dat2)
mean(dat2, na.rm = TRUE)
mf(dat2, mean, na.rm = TRUE)
最后三行给出
> mean(dat2)
[1] NA
> mean(dat2, na.rm = TRUE)
[1] 0.5377895
> mf(dat2, mean, na.rm = TRUE)
[1] 0.5377895
R中的“数据集”通常意味着一个数据帧并且没有median.data.frame,所以你需要同时使用lapply和do.call:
df <- data.frame(x=rnorm(10), y=rnorm(10))
mf = function(data, option="mean") {lapply( data,
function(col) do.call(option, list(col))) }
mf(df)
#-------------
$x
[1] 0.01646814
$y
[1] 0.5388518
你没有指出应该做什么“级别”,所以我把它排除在等式之外,
> mf(df, sd)
$x
[1] 1.169847
$y
[1] 0.8907117