我在使用apply函数时遇到一些问题,在不需要时将参数传递给函数。我知道apply不知道如何处理可选参数,只是在函数上传递它们。
但无论如何,这就是我想做的事情:
首先,我想指定一个我想要使用的函数列表。
functions <- list(length, sum)
然后我想创建一个在数据集上应用这些指定函数的函数。
myFunc <- function(data, functions) {
for (i in 1:length(functions)) print(apply(X=data, MARGIN=2, FUN=functions[[i]]))
}
这很好用。
data <- cbind(rnorm(100), rnorm(100))
myFunc(data, functions)
[1] 100 100
[1] -0.5758939 -5.1311173
但我还想为某些功能使用额外的参数,例如
power <- function(x, p) x^p
哪个不能正常工作。如果我将myFunc
修改为:
myFunc <- function(data, functions, ...) {
for (i in 1:length(functions)) print(apply(X=data, MARGIN=2, FUN=functions[[i]], ...))
}
functions
functions <- list(length, sum, power)
然后尝试我的功能
myFunc(data, functions, p=2)
Error in FUN(newX[, i], ...) :
2 arguments passed to 'length' which requires 1
我该如何解决这个问题?
对不起文字墙。谢谢!
答案 0 :(得分:4)
您可以使用Curry
中的functional
来修复所需的参数,将该函数放入要应用的函数列表中,最后遍历此函数列表:
library(functional)
power <- function(x, p) x^p
funcs = list(length, sum, Curry(power, p=2), Curry(power, p=3))
lapply(funcs, function(f) apply(data, 2 , f))
使用您的代码,您可以使用:
functions <- list(length, sum, Curry(power, p=2))
myFunc(data, functions)
答案 1 :(得分:1)
我主张使用Colonel的Curry
方法,但如果你想坚持基础R,你可以随时:
funcs <- list(length, sum, function(x) power(x, 2))
大致是Curry
最终在做什么
答案 2 :(得分:0)
一种选择是使用每个函数所需的参数传递列表中的参数。您可以使用apply
将这些参数添加到c
所需的其他参数中,然后使用do.call
来调用该函数。像这样的东西。我还将所有输出包装在列表中,而不是使用print
;您的使用可能会有所不同。
power <- function(x, p) x^p
myFunc <- function(data, functions, parameters) {
lapply(seq_along(functions), function(i) {
p0 <- list(X=data, MARGIN=2, FUN=functions[[i]])
do.call(apply, c(p0, parameters[[i]]))
})
}
d <- matrix(1:6, nrow=2)
functions <- list(length, sum, power)
parameters <- list(NULL, NULL, p=3)
myFunc(d, functions, parameters)
答案 3 :(得分:0)
您可以使用lazyeval包:
library(lazyeval)
my_evaluate <- function(data, expressions, ...) {
lapply(expressions, function(e) {
apply(data, MARGIN=2, FUN=function(x) {
lazy_eval(e, c(list(x=x), list(...)))
})
})
}
并像这样使用它:
my_expressions <- lazy_dots(sum = sum(x), sumpow = sum(x^p), length_k = length(x)*k )
data <- cbind(rnorm(100), rnorm(100))
my_evaluate(data, my_expressions, p = 2, k = 2)