plyrsummary вызывает только глобальные функции

Я пытаюсь передать функцию (weight.func) другой функции (оболочке), которая вызывает ddply. Я хочу, чтобы ddply использовал эту функцию (weight.func) как часть своих вычислений. Я получаю результат, который хочу, когда weight.func установлен «глобально», но не когда он передается как анонимная функция в оболочку.

Могу ли я заставить 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

Второй выход – цель. Любая помощь приветствуется! (Включая способ выполнения той же задачи, не основанный на plyr.)

Приведенный выше пример — игрушечный. Это самый простой случай, когда я мог воспроизвести поведение.


person Nathan VanHoudnos    schedule 27.11.2010    source источник


Ответы (4)


вы можете использовать совокупность:

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  )

в этом случае вы можете указать имя внутри функции.

person kohske    schedule 27.11.2010
comment
и вы можете сделать то же самое с помощью ddply без суммирования. см. редактирование. - person kohske; 27.11.2010

Это известная ошибка в plyr: https://github.com/hadley/plyr/issues#issue/3

person hadley    schedule 30.11.2010
comment
Я не думал, что у Plyr есть ошибки. Я просто подумал, что не знаю, как правильно использовать программное обеспечение. :) (И ваши пакеты потрясающие, кстати.) - person Nathan VanHoudnos; 01.12.2010

Я не совсем уверен, какое изменение я сделал (удалив пробелы после «суммы» или изменив 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
person IRTFM    schedule 27.11.2010
comment
Это не работает для меня. Поскольку вы звоните: wrapper( sampleData, weight.func=weight.func ), значит, weight.func все еще висит как глобал. Пример: rm(weight.func); wrapper( sampleData, weight.func=function(x) (x+.001)^-1 ) не работает. - person Nathan VanHoudnos; 27.11.2010