2010-11-27 5 views
3

ddply를 호출하는 다른 함수 (래퍼)에 함수 (weight.func)를 전달하려고합니다. 나는 ddply가 그 함수 (weight.func)를 계산의 일부로 사용하기를 원한다. weight.func가 '전역 적으로'설정되었지만 래퍼에 익명의 함수로 전달되는 경우가 아니라면 원하는 출력을 얻습니다.plyr 요약 만 글로벌 함수를 호출합니다.

내가 원하는 것을하기 위해 ddply를 얻을 수 있습니까? 다음은 코드 예제입니다.

> print(sampleData) 
    studentId problem part  workerId rating 
1  8001 problem26 partA A127R5QI5OGBIK 0.0 
2  8001 problem26 partA A1FCLYRBAB430F 0.0 
3  8001 problem26 partA A25FZQY34C6RVO 0.0 
4  8001 problem26 partA A3G0MO562MHMZ3 0.5 
5  8001 problem26 partA A3RB9ZOIUC3NWG 2.0 
6  8001 problem26 partB A1FCLYRBAB430F 0.5 
7  8001 problem26 partB A1XRDZKSJBWY8Q 0.5 
8  8001 problem26 partB A22CRWMZUX7FFR 0.5 
9  8001 problem26 partB A25FZQY34C6RVO 1.0 
10  8001 problem26 partB A3G0MO562MHMZ3 0.5 
11  8001 problem27 partA A1ET309DW6M2XA 2.0 
12  8001 problem27 partA A1FCLYRBAB430F 0.0 
13  8001 problem27 partA A22CRWMZUX7FFR 0.0 
14  8001 problem27 partA A25FZQY34C6RVO 0.0 
15  8001 problem27 partA A3G0MO562MHMZ3 0.0 
16  8001 problem27 partB A1FCLYRBAB430F 1.0 
17  8001 problem27 partB A22CRWMZUX7FFR 0.0 
18  8001 problem27 partB A25FZQY34C6RVO 0.0 
19  8001 problem27 partB A2U9676210WST5 0.0 
20  8001 problem27 partB A3G0MO562MHMZ3 0.0 
21  8002 problem26 partA A127R5QI5OGBIK 0.0 
22  8002 problem26 partA A1FCLYRBAB430F 0.5 
23  8002 problem26 partA A22CRWMZUX7FFR 0.0 
24  8002 problem26 partA A25FZQY34C6RVO 2.0 
25  8002 problem26 partA A3G0MO562MHMZ3 0.5 
26  8002 problem26 partB A17EHJZNJGNRAN 2.0 
27  8002 problem26 partB A1FCLYRBAB430F 0.0 
28  8002 problem26 partB A2IPRDTE6B4TAB 0.0 
29  8002 problem26 partB A3G0MO562MHMZ3 0.0 
30  8002 problem26 partB A6SON3OS15XKA 0.0 
31  8002 problem27 partA A1FCLYRBAB430F 0.0 
32  8002 problem27 partA A25FZQY34C6RVO 0.0 
33  8002 problem27 partA A2IPRDTE6B4TAB 0.0 
34  8002 problem27 partA A2U9676210WST5 0.0 
35  8002 problem27 partA A3G0MO562MHMZ3 0.0 
36  8002 problem27 partB A1FCLYRBAB430F 0.0 
37  8002 problem27 partB A1V52SSKROBV8E 2.0 
38  8002 problem27 partB A25FZQY34C6RVO 2.0 
39  8002 problem27 partB A2IPRDTE6B4TAB 0.0 
40  8002 problem27 partB A3G0MO562MHMZ3 0.0 
> 
> #Make a wrapper 
> wrapper <- function (ratingData, weight.func) { 
+ print(weight.func) #prove that the function is being passed 
+ ddply(ratingData, c('studentId','problem','part'), summarize, 
+   sum.weights = sum (weight.func(rating) )) 
+ } 
> wrapper(sampleData, weight.func=function(x) (x+.001)^-1 ) 
function(x) (x+.001)^-1 
Error in data.frame(sum.weights = sum(weight.func(rating))) : 
    could not find function "weight.func" 
> 
> #'globally' declare weight.func 
> weight.func <- function(x) (x+.001)^-1 
> wrapper(sampleData, weight.func=NULL ) 
NULL 
    studentId problem part sum.weights 
1  8001 problem26 partA 3002.495758 
2  8001 problem26 partB 8.983033 
3  8001 problem27 partA 4000.499750 
4  8001 problem27 partB 4000.999001 
5  8002 problem26 partA 2004.491766 
6  8002 problem26 partB 4000.499750 
7  8002 problem27 partA 5000.000000 
8  8002 problem27 partB 3000.999500 

두 번째 출력이 목표입니다. 어떤 도움을 주셔서 감사합니다! (동일한 작업을 수행하기위한 비결정 기반 방법 포함)

위의 예는 장난감 예입니다. 그것은 행동을 재현 할 수있는 가장 간단한 경우입니다.

답변

2

당신이 집계 사용할 수 있습니다 : 당신이 당신 자신에 의해 그것을 할 필요가 이름 싶다면, 집계 된 열 이름이 자동으로 결정됩니다

w2 <- function(d, f){ 
    aggregate(rating~studentId+problem+part, function(x)sum(f(x)), data=d) 
} 

w2(sampleData, function(x) (x+.001)^-1 ) 

참고.

당신은 ddply없이하여 같은 일이 당신이 함수 내에서 이름을 지정할 수 있습니다이 경우

wrapper <- function (ratingData, weight.func) { 
    ddply(ratingData, c('studentId','problem','part'), function(x)c(sum.weights=sum(weight.func(x$rating)))) 
} 

wrapper(sampleData, weight.func=function(x) (x+.001)^-1 ) 

을 요약 할 수 있습니다.

+0

완벽한, 고마워요! –

+0

그리고 요약하지 않고 ddply로 같은 것을 할 수 있습니다. 편집을 참조하십시오. – kohske

0

내가 ("합"후 공간을 복용하거나 실제 함수 또는 < < 뭔가 >>에 NULL 변경) 만든 변경을 정확하게 모르겠지만이 지금 작동합니다

wrapper <- function (ratingData, weight.func=weight.func) { 
     ddply(ratingData, .variables=c('studentId','problem','part'), 
      .fun=summarise, sum.weights = sum(weight.func(rating) )) 
    } 

wrapper(sampleData, weight.func=weight.func ) 
    studentId problem part sum.weights 
1  8001 problem26 partA 3002.495758 
2  8001 problem26 partB 8.983033 
3  8001 problem27 partA 4000.499750 
4  8001 problem27 partB 4000.999001 
5  8002 problem26 partA 2004.491766 
6  8002 problem26 partB 4000.499750 
7  8002 problem27 partA 5000.000000 
8  8002 problem27 partB 3000.999500 
+0

나를 위해 작동하지 않습니다. 당신이 'wrapper (sampleData, weight.func = weight.func)'를 호출했기 때문에'weight.func'가 여전히 전역으로 사용 중임을 의미합니다. 예 :'rm (weight.func); 래퍼 (sampleData, weight.func = function (x) (x + .001)^- 1)'가 작동하지 않습니다. –

2

이것은 plyr에서 알려진 버그 : https://github.com/hadley/plyr/issues#issue/3

+1

플라이어가 버그가 있다고 생각하지 않았습니다. 나는 소프트웨어를 사용하는 올바른 방법을 몰랐다. :) (그리고 당신의 패키지는 훌륭합니다, btw.) –

0

plyr에서이 문제 (https://github.com/hadley/plyr/issues/3)에 업데이트 :

사용 plyr에서 '여기'기능, 그냥 대체 여기 '로,'요약 ' (요약) '을 통해 ddply가 호출 된 환경에 액세스 할 수 있습니다.

wrapper <- function(ratingData, weight.func){ 
      ddply(ratingData, c('studentId','problem','part'), 
       here(summarize), # here(summarize)! 
       sum.weights = sum(weight.func(rating)) 
       ) 
      } 
관련 문제