2012-09-12 1 views
1

다양한 가중치를 사용하여 data.frames 목록을 보유하고 있으며 해당 열을 조작하고 싶습니다.Reduce에 여러 인수 전달

예를 들어 두 번째 열에서 첫 번째 열을 뺍니다 (해결됨, 아래 참조). 또는 두 번째 두 번째 (미해결)에서 첫 번째와 세 번째를 뺍니다.

this 질문에 대한 응답으로 얻은 관대 한 도움 덕분에, Reduce을 사용하여 2 차원에서 문제없이 문제를 해결할 수 있습니다.

나는 가중치로 그리고 더 높은 차원에서 작동 할 수있는 유연성을 원합니다.

내가 지금까지있는 것은 :

내가 무엇을 말할 수에서
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으로 길게 할 수 있지만 일부 루프는 수행 할 수 있지만은 처럼 보이지 않습니다.

가중치 벡터를 전달하는 방법이 있습니까?

이상적으로는 w = c(-1, 2, -1)과 같은 인수를 colDiff (또는 Reduce) 함수 또는 이와 비슷한 함수에 전달하는 것이 좋습니다.

+1

있을 때 데이터를 3D 배열에 저장하는 것이 좋습니다. 그러면 당신이하려고하는 것은'% * %'(행렬 곱셈)과 아마도'aperm'을 가진 한 줄짜리 행렬에서 할 수 있습니다. – flodel

+0

그렇습니다. 데이터 준비가 완료된 모습입니다. 고마워, 내가 조사 할거야. – ricardo

답변

3

참이면 Reduce은 복수의 인수를 허용하도록 설정되지 않으며 각 감소마다 2 개만 허용됩니다. 따라서 목록에있는 요소를 미리 곱해야하는 것이 가장 쉽습니다 (Reduce -ing).

다음은 colDiff 함수 정의 내에서 mapply을 사용하여이를 수행하는 솔루션입니다.

colDiff의 정의를 변경하여 가중치 벡터를 허용하고 mapply 을 사용하여 SIMPLIFY = F을 적용하십시오.

편집

코멘트 비추어

, 가중

길이 (X) == 열 개수에 따라 길이에 의해 rev

가중에 대한 필요가 존재하지 1 -> w = 1
길이 (x) == 2 -> w = c (-1,1),
길이 (x) == 3 -> w = c (-1, 2, -1) ,
길이 (x) == 4 -> 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)) 
    } 

그렇다면이 같은 것을 당신은 또한 함수형 프로그래밍을 테마로 유지하고있는 Map를 사용할 수

tradeList <- lapply(tradeLegsList, colDiff) 

를 작동합니다 SIMPLIFY = F

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

mapply에 대한 간단한 래퍼는 또한 내에서 가중치를 prefine 수 function colDiff (더 쉬울 수도 있음). weighting[[2]] 2 열이있을 경우에 대한 가중되고 weighting[[3]] 데이터, 당신의 예처럼 즉, 모든`numeric`이며, 각 목록 요소가 나는 높은 것, 동일한 치수가있는 경우 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 엘리먼트 중 하나가'aaa','bbb','ccc' 컬럼을 가진 data.frame 인 경우, 함수는'-ccc-2bbb -aaa'를' W = c (-1,2,1)'. (Reduce 호출에서 x의 순서를 뒤집 으면 – mnel

+0

사과) w = c (-1, 2, -1)의 결과는'- aaa + 2bbb -ccc'입니다. 완전한 해결책은 가중치를 적절한 순서로 바꾸어'Replace'에서'+'를 사용할 수있는 함수를 작성하는 것이라고 생각하십니까? – ricardo