2012-09-12 96 views
1

我有一个data.frames列表,并希望使用各种权重对它们的列进行操作。将多个参数传递给Reduce

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

感谢在回答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

如果数据是像在你的例子,即所有'numeric'和每个列表元素具有相同的尺寸,然后我会强烈建议您将数据存储在3D数组中。那么你想做的事情可以用'%*%'(矩阵乘法)和可能的'aperm'完成。 – flodel

+0

是的,数据一旦准备好就会看起来如何。谢谢,我会调查。 – ricardo

回答

3

确实,Reduce不适用于允许多个参数,每个简化只有两个参数。因此,最容易预清单列表中的元素是Reduce -ing。

下面是在colDiff函数定义中使用mapply这样做的解决方案。

更改您的colDiff的定义以允许使用重量向量,并将其应用于mapplySIMPLIFY = F

EDIT

在评论的光,加权取决于列数和因此不需要用于rev

加权由长度

长度(X)== 1 - > w = 1
length(x)== 2 - > w = c(-1,1),
length(x)== 3 - > w = c(-1,2,-1) ,
length(x)== 4 - > w = C(-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这是一个简单打包mapplySIMPLIFY = F

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

你也可以prefine内的加权函数colDiff(可能更容易)。 weighting[[2]]被加权时,有2列,用于weighting[[3]]当存在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)) 
     } 
+0

+1,谢谢。我认为你需要在'Reduce'表单中修改操作符号。即使'Reduce(' - ',...','Reduce('+',...'...但打破了'w = NULL'的情况......也许'e2 = -w' ? – ricardo

+0

如果你的tradeLegList元素中有一个是一个data.frame,并且列'aaa','bbb','ccc',那么函数应该会给出'-ccc-2bbb - aaa', w = c(-1,2,1)'(假设你在Reduce调用 – mnel

+0

apologies中颠倒了x的顺序,'w = c(-1,2,-1)'所需的结果是' aaa + 2bbb -ccc'。你认为完整的解决方案是编写一个函数来调整权重的适当顺序,这样我们就可以在'Replace'中使用'+'了吗? – ricardo