我有一个过滤函数列表f1,f2,f3,f4,....
,它将矩阵m
和许多选项作为输入,并返回矩阵行的子集作为输出。现在我希望能够以有序的方式定义一些元过滤功能设置metaf1, metaf2, metaf3,...
,它将指定指定nr个过滤功能的顺序应用,例如,首先是f2
,然后是f3
,每个都使用给定的选项。我想将这些过滤设置存储在类"metafiltering"
的列表中,然后让另一个函数应用给定metafiltering
对象中指定的过滤步骤。我的想法是能够以这种方式允许以有序的方式存储和应用过滤设置。我将如何以最优雅的方式在R中实现这一目标?或者是否有其他方便的方法可以实现这样的目标?
编辑:举个例子,说我有矩阵
m=replicate(10, rnorm(20))
和过滤功能(这些只是示例,显然我的更复杂:-))
f1=function(m,opt1,opt2) {
return(m[(m[,2]>opt1)&(m[,1]>opt2),])
}
f2=function(m,opt1) {
return(m[(m[,3]>opt1),])
}
我已经定义了特定类的以下metafiltering
设置,这些设置将指定必须顺序应用于矩阵m的两个函数
metafilterfuncs=list(fun1=f1(opt1=0.1,opt2=0.2),fun2=f2(opt1=0.5))
class("metafilterfuncs")="metafiltering"
我的问题是如何使用指定的函数和设置将任意metafiltering
函数对象的过滤步骤应用于给定的矩阵m?
答案 0 :(得分:2)
您可以这样做:
您可以定义一种函数pieplines,其中为每个函数赋予优先级。
pipelines <- c(f1=100,f2=300,f3=200)
我在这里定义了3个虚拟函数用于测试:
f1 <- function(m,a) m + a
f2 <- function(m,b) m + b
f3 <- function(m,c) m + c
对于每个函数,将参数存储在另一个列表中:
args <- list(f1=c(a=1),f2=c(b=2),f3=c(c=3))
然后你应用你的功能:
m <- matrix(1:2,ncol=2)
for (func in names(pipelines[order(pipelines)]))
{
m <- do.call(func,list(m,args[[func]]))
}
答案 1 :(得分:1)
pryr有一个函数compose
,就像你需要的那样,但它并没有完全削减它。 compose函数需要逐个给出函数,而不是列表,并且它不能接受参数。它也奇怪地放在那个包里。类似的功能可以在 plyr 中找到,即每个。但是这个函数不是按顺序应用函数,而是单独应用并输出一个命名向量(列表?)。
agstudy上面提供了一个解决方案,但它遇到了一个问题:它只能采用标量参数,因为它在命名向量中给出了参数。解决方案是使用命名列表。因此,这里有一个改进的功能来替换 pryr 中的那个。
compose2 = function(x, funcs, args, msg_intermediate = F) {
if (length(funcs) != length(args)) stop("length of functions and arguments must match")
for (i in seq_along(funcs)) {
x = do.call(what = funcs[[i]], args = c(x, args[[i]]))
if ((i != length(funcs)) && msg_intermediate) message(x)
}
x
}
msg_intermediate
是一个很好的调试参数,可以向中间结果发送消息,因此可以更容易地理解会发生什么。
测试它:
adder = function(x, n) x + n
compose2(0,
funcs = list(adder, adder, adder),
args = list(list(n = 1), list(n = 2), list(n = 3)),
msg_intermediate = T
)
输出:
1
3
[1] 6
这是你取0,然后加1(= 1),然后加2(= 3),然后加3(= 6)得到的。
compose2的args
参数采用列表列表,因此可以提供非标量函数参数。这是一个例子:
add_div = function(x, n, d) (x + n) / d
compose2(0,
funcs = list(add_div, add_div, add_div),
args = list(list(n = 1, d = 1), list(n = 2, d = 2), list(n = 3, d = 3)),
msg_intermediate = T
)
输出:
1
1.5
[1] 1.5
当你取0,加1,除以1(= 1),然后取1,加2然后除以2(= 1.5),然后取1.5,加3然后除以3,得到的是(= 1.5)。