2010-07-18 17 views
9

Sto provando a fare una media ponderata in stile "group by" in R. Con alcuni media di base il codice seguente (usando il pacchetto plyr di Hadley) ha funzionato bene.group by in R, ddply con weighted.mean

ddply(mydf,.(period),mean) 

Se uso lo stesso approccio con weighted.mean ottengo il seguente errore " 'x' e 'w' deve avere la stessa lunghezza", che non capisco perché la parte weighted.mean lavora fuori ddply.

weighted.mean(mydf$mycol,mydf$myweight) # works just fine 
ddply(mydf,.(period),weighted.mean,mydf$mycol,mydf$myweight) # returns the erros described above 
ddply(mydf,.(period),weighted.mean(mydf$mycol,mydf$myweight)) # different code same story 

ho pensato di scrivere una funzione personalizzata invece di utilizzare weighted.mean e poi passarlo a ddply o anche scrivere qualcosa di nuovo da zero con sottoinsieme. Nel mio caso sarebbe troppo lavoro spero, ma ci dovrebbe essere una soluzione più intelligente con quello che c'è già.

thx per eventuali suggerimenti in anticipo!

risposta

17

Utilizzare una funzione anonima:

> ddply(iris,"Species",function(X) data.frame(wmn=weighted.mean(X$Sepal.Length, 
+                X$Petal.Length), 
+            mn=mean(X$Sepal.Length))) 
    Species  wmn mn 
1  setosa 5.016963 5.006 
2 versicolor 5.978075 5.936 
3 virginica 6.641535 6.588 
> 

Questo calcola una media pesata di Sepal.Length (ponderato per Petal.Length) così come media non ponderata e restituisce entrambi.

+0

Questo è bello. Non aveva molto a che fare con le funzioni anonime finora. sembra davvero la pena dare un'occhiata. Non ho ancora trovato la sintassi/idea, ma ci penserò, grazie per il tuo aiuto! Hai bisogno di stampare tutto in una riga a causa di nessun "{}" in là? Dove posso imparare qualcosa sulle funzioni anonime? –

+1

Bene, * tutti * queste funzioni '* apply',' by', ... usano funzioni anonime, quindi dovresti trovare molti esempi. Le parentesi graffe sono necessarie quando si raggruppa più di un comando. Infine, non hai una funzione anonima - puoi anche definirne una tua - ma usarle risparmia sulla digitazione :) –

+0

e riguardo 'lapply (split (iris, species), weighted.mean)' o smth come quella ? – aL3xa

20

Usa riassumere (o riassumere):

ddply(iris, "Species", summarise, 
    wmn = weighted.mean(Sepal.Length, Petal.Length), 
    mn = mean(Sepal.Length)) 
+0

Quando provo questo modulo ottengo 'Errore in is.list (da): 'by' manca. L'output del debugger è impenetrabile. Qualche indizio da dove sarebbe venuto questo errore? Chiunque fosse interessato a provare i miei dati e la chiamata 'ddply()'? –

+4

Anche questo errore si verifica su un codice simile. L'errore si verifica solo in RStudio. È dovuto al fatto che 'Hmisc :: riepilogo 'è superiore a' plyr :: ddply' nell'elenco 'search()'. [Vedi questo link] (https://groups.google.com/forum/?fromgroups=#!topic/manipulatr/DF__5YfwE68). Risolvilo sostituendo 'riepiloga' con' riepiloga': funziona e non crea conflitto con 'Hmisc'. Benvenuto nell'inferno della dipendenza! –

+6

Oppure sii esplicito e usa 'plyr :: sumarize' – hadley