我有一个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
)函数......或类似的东西。
答案 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))
}