2012-04-16 10 views
19

Chciałbym móc wysłać nazwę kolumny do połączenia, które wykonuję do ddply. Przykładem ddply wezwanie:Wysyłanie w kolumnie Nazwa do ddply z funkcji

ddply(myData, .(MyGrouping), summarise, count=sum(myColumnName)) 

Jeśli mam ddply owinięty wewnątrz innej funkcji możliwe jest owinąć to tak, że może przejść w dowolnej wartości jako myColumnName do funkcji wywołującej?

+0

Czy masz powtarzalny przykład (z danymi, np. za pomocą tęczówki)? –

+0

@static_rtti szukasz konkretnie odpowiedzi 'plyr'? To pytanie jest bardzo stare i są obecnie znacznie bardziej zaawansowane pakiety. –

+0

Cóż, używam plyr (i nie znam bardziej zaawansowanych pakietów), ale jeśli potrafisz udzielić odpowiedzi na ten sam problem z inną paczką, to też by mnie zainteresowało. –

Odpowiedz

11

Musi istnieć lepszy sposób. I nie mogłem wymyślić, jak zrobić to z podsumowaniem.

my.fun <- function(df, count.column) { 
    ddply(df, .(x), function(d) sum(d[[count.column]])) 
} 

dat <- data.frame(x=letters[1:2], y=1:10) 

> my.fun(dat, 'y') 
    x V1 
1 a 25 
2 b 30 
> 
+0

Możesz przekazać count.column bezpośrednio do funkcji w 'ddply' jak w:' ddply (df,. (X), function (d) sum (d [[count.column]])) 'oznacza mniej kodu i unikanie 'eval'. –

+0

@TylerRinker tak, że eval był holdover od kiedy próbowałem zrobić to z podsumowaniem. edytowane. – Justin

+0

Próbowałem tego również (ale ponieważ tak naprawdę nie używam już nic plyr), nie mogłem również wymyślić, jak sprawić, by działał z podsumowaniem. –

7

To wydaje się działać, choć prawdopodobnie będzie czystsze (i bezpieczniejsze), aby uniknąć summarise w takiej sytuacji i napisać własną funkcję anonimową jak wskazano Justin.

yr <- "year" 

summarise(baseball, 
duration = max(eval(parse(text = yr))) - min(eval(parse(text = yr)))) 
4

Jak to powiedział @David Arenburg, to pytanie jest dość stare. Dzisiaj pakiet data.table lub dplyr może dać taki sam rezultat przy znacznie większej prędkości. To jest wersja data.table odpowiedzi.

library(data.table) 
my.fun <- function(myData, MyGrouping, myColumnName) { 
    setDT(myData)[, lapply(.SD, sum), by=MyGrouping, .SDcols=myColumnName] 
} 
0

Chyba znalazłem sposób, że działa z przedstawiono podsumowanie. Nie jestem pewien, czy rozumiem dlaczego, ponieważ nie jestem ekspertem w kontaktach ze środowiskami w R, ale tutaj jest rozwiązanie:

> library(plyr) 
> 
> 
> 
> ########################### 
> # Creating test DataFrame # 
> ########################### 
> 
> x <- 1:15 
> 
> set.seed(1) 
> y <- letters[1:3][sample(1:3, 15, replace = T)] 
> 
> df <- data.frame(x, y) 
> 
> ### check df 
> df 
    x y 
1 1 a 
2 2 b 
3 3 b 
4 4 c 
5 5 a 
6 6 c 
7 7 c 
8 8 b 
9 9 b 
10 10 a 
11 11 a 
12 12 a 
13 13 c 
14 14 b 
15 15 c 
> 
> 
> ##################### 
> # auxiliar function # 
> ##################### 
> evalString <- function(s) { 
+ eval(parse(text = s), parent.frame()) 
+ } 
> 
> 
> ### columnName input 
> columnName <- 'x' 
> 
> ### call with columnName as input 
> xMeans <- ddply(df, 
+     'y', 
+     summarise, 
+     mean = mean(evalString(columnName))) 
> 
> 
> ### regular call to ddply 
> xMeans2 <- ddply(df, 
+     'y', 
+     summarise, 
+     mean = mean(x)) 
> 
> 
> ### Compare Results 
> xMeans 
    y mean 
1 a 7.8 
2 b 7.2 
3 c 9.0 
> xMeans2 
    y mean 
1 a 7.8 
2 b 7.2 
3 c 9.0 
> 

EDIT: Można użyć funkcji get z pakietu podstawowego, jak sugeruje tutaj: ddply: how do I pass column names as parameters?

> xMeans3 <- ddply(df, 
+     'y', 
+     summarise, 
+     mean = mean(get(columnName))) 
> 
> xMeans3 
    y mean 
1 a 7.8 
2 b 7.2 
3 c 9.0 
Powiązane problemy