将多个参数传递给Reduce

时间:2012-09-12 04:14:43

标签: r reduce

我有一个data.frames列表,并希望使用各种权重对其列进行操作。

例如,从第二列中减去第一列(已解决,见下文);或者从第二次(未解决的)两次减去第一次和第三次。

感谢在回答this问题时获得的慷慨帮助,我使用Reduce在没有权重的情况下解决了二维问题。

我希望能够灵活地使用重量 - 以及更高的角度。

到目前为止我所拥有的是:

priceList <- data.frame(aaa = rnorm(100, 100, 10), bbb = rnorm(100, 100, 10), 
                        ccc = rnorm(100, 100, 10), ddd = rnorm(100, 100, 10), 
                        eee = rnorm(100, 100, 10), fff = rnorm(100, 100, 10), 
                        ggg = rnorm(100, 100, 10)
                        )

colDiff <- function(x) 
    {
        Reduce('-', rev(x))
    }

tradeLegsList <- combn(names(priceList), 3, function(x) priceList[x], simplify = FALSE)

tradeList <- lapply(tradeLegsList, colDiff)

据我所知,Reduce并非旨在采用多个参数。

我可以用2* tradeLegsList[[1]]$bbb - tradeLegsList[[1]]$aaa - tradeLegsList[[1]]$ccc以及一些循环来完成这个任务,但它似乎不是 R路

有没有办法传入权重向量?

理想情况下,我会将w = c(-1, 2, -1)之类的参数传递给colDiff(或Reduce)函数......或类似的东西。

1 个答案:

答案 0 :(得分:3)

是的,Reduce不适合允许多个参数,每次减少只需两个参数。因此,最简单的方法是预先列出您Reduce - 列表中的元素。

以下是使用mapply函数定义中的colDiff执行此操作的解决方案。

更改colDiff的定义以允许权重向量,并使用mapply应用此权重  与SIMPLIFY = F

修改

根据评论,加权取决于列数,而不需要rev

按长度加权

  

length(x)== 1 - &gt; w = 1
  length(x)== 2 - &gt; w = c(-1,1),
  length(x)== 3 - &gt; w = c(-1,2,-1),
  length(x)== 4 - &gt; w = c(-1,1,-1,+ 1)

weighting <- function(i){
  switch(i, 1, c(-1,1), c(-1,2,-1), c(-1,1,-1, 1))
}
colDiff <- function(x) 
    {
        w = weighting(length(x))
        Reduce('+', mapply('*', x, e2 = w, SIMPLIFY = F))
    }

然后这样的事情会起作用

tradeList <- lapply(tradeLegsList, colDiff)

你也可以继续使用函数式编程主题,并使用Map这是mapply的简单包装器SIMPLIFY = F

colDiff <- function(x) 
        {
            w = weighting(length(x))
            Reduce('+', Map('*', x , e2 = w))
        }

您还可以在函数colDiff中预定义权重(这可能更容易)。 当有2列时weighting[[2]]为加权,当有3列时为weighting[[3]]

colDiff <- function(x) 
        {
         weighting <- list(1, c(-1,1), c(-1,2,-1), c(-1,1,-1, 1))             
            w = weighting[[length(x)]]
            Reduce('+', Map('*', x , e2 = w))
        }