2013-04-18 12 views
6

Chcę napisać tę samą funkcję do wielu kolumn za pomocą funkcji ddply, ale próbuję pisać dalej w jednej linii, chcę zobaczyć, czy jest lepszy sposób na zrobienie tego?Pakiet plyr wypisujący tę samą funkcję w wielu kolumnach

Oto prosty wersja danych:

data<-data.frame(TYPE=as.integer(runif(20,1,3)),A_MEAN_WEIGHT=runif(20,1,100),B_MEAN_WEIGHT=runif(20,1,10)) 

i chcę, aby dowiedzieć się sumę kolumn A_MEAN_WEIGHT i B_MEAN_WEIGHT w ten sposób:

ddply(data,.(TYPE),summarise,MEAN_A=sum(A_MEAN_WEIGHT),MEAN_B=sum(B_MEAN_WEIGHT)) 

ale w moim obecnym danych mam więcej niż 8 "* _MEAN_WEIGHT", i jestem zmęczony pisaniem ich 8 razy jak

ddply(data,.(TYPE),summarise,MEAN_A=sum(A_MEAN_WEIGHT),MEAN_B=sum(B_MEAN_WEIGHT),MEAN_C=sum(C_MEAN_WEIGHT),MEAN_D=sum(D_MEAN_WEIGHT),MEAN_E=sum(E_MEAN_WEIGHT),MEAN_F=sum(F_MEAN_WEIGHT),MEAN_G=sum(G_MEAN_WEIGHT),MEAN_H=sum(H_MEAN_WEIGHT)) 

Czy czy jest lepszy sposób na napisanie tego? Dziękuję za pomoc !!

Odpowiedz

6

plyr -centred podejściem jest użycie colwise

np

ddply(data, .(TYPE), colwise(sum)) 
    TYPE A_MEAN_WEIGHT B_MEAN_WEIGHT 
1 1  319.8977  60.80317 
2 2  621.6745  37.05863 

można przekazać nazwy kolumn jako argument .col jeśli chcesz tylko podzbiór

Można również użyć numcolwise lub catcolwise, aby zadziałał na nume tylko kolumny ric lub kategoryczne.

uwaga, że ​​można użyć sapply w miejscu najbardziej podstawowego wykorzystania colwise

ddply(data, .(TYPE), sapply, FUN = 'mean') 

idiomatyczne data.table sposobem jest użycie lapply(.SD, fun)

np

dt <- data.table(data) 
dt[,lapply(.SD, sum) ,by = TYPE] 
    TYPE A_MEAN_WEIGHT B_MEAN_WEIGHT 
1: 2  621.6745  37.05863 
2: 1  319.8977  60.80317 
+0

Dzięki @mnel! jeszcze jedno pytanie, nie wydaje mi się, żebym mógł zapisać je w ten sposób ddply (dane,. (TYPE), colwise (suma,. (A_MEAN_WEIGHT)), colwise (sqrt,. (B_MEAN_WEIGHT))), więc jeśli I chcesz mieć dwie różne funkcje w wielu kolumnach, muszę napisać je dwa razy? – linp

4

Spróbuj tego:

ddply(data, .(TYPE), colSums) 

Oto (wolniej) odpowiednik powyższego, które mogą być manipulowane, aby umieścić dowolną funkcję zamiast zsumowanie:

ddply(data, .(TYPE), function(x) {apply(x, 2, sum)}) 

A jeśli chcesz zachować .(TYPE) kolumna smth jak to zrobi:

ddply(data, .(TYPE), function(x) {apply(x[,names(x) != "TYPE"], 2, sum)}) 

jeszcze lepiej użyć data.table zamiast plyr:

library(data.table) 
dt = data.table(data) 

# just sums 
dt[, data.table(t(colSums(.SD))), by = TYPE] 

# sum for "A" and "B", and sqrt(sum) for "C" and "D" 
# note: you will have to call setnames() to fix the column names after 
dt[, data.table(t(colSums(.SD[, c("A_MEAN_WEIGHT", "B_MEAN_WEIGHT"), with = F])), 
       t(apply(.SD[, c("C_MEAN_WEIGHT", "D_MEAN_WEIGHT"), with = F], 
         2, function(x) sqrt(sum(x))))), 
    by = TYPE] 
+0

Działa świetnie! Dzięki @eddi !! – linp

+0

Emm ... pytanie uzupełniające, co jeśli mam 16 kolumn i chcę zrobić sumę dla 8 z nich, a sqrt (suma) z pozostałych 8 ... – linp

+0

Można np. uruchom powyższą komendę dwukrotnie - raz z każdą funkcją i filtruj według kolumn, które chcesz (np. wykonując 'names (x)% w% c (" column_a "," column_b ", ...)' w 'apply' lub w kolumnie numer lub cokolwiek jest odpowiednie dla twoich danych), a następnie "cbind" wynik – eddi

Powiązane problemy