2013-09-24 21 views
9

Ich möchte die gleichen Ergebnisse wie in R summarizing multiple columns with data.table aber für mehrere zusammenfassende Funktionen.R multiple Statistiken für mehrere Spalten mit data.table

Hier ist ein Beispiel

data <- as.data.table(list(x1 = runif(200), x2 = 10*runif(200), group = factor(sample(letters[1:2])))) 

res <- data[, rbindlist(lapply(.SD, function(x) { 
       return(list(name = "varname", mean = mean(x), sd = sd(x))) 
      })) 
      , by = group, .SDcols = c("x1", "x2") 
      ] 

und das folgende Ergebnis:

group name  mean  sd 
1:  b varname 0.5755798 0.2723767 
2:  b varname 5.5108886 2.7649262 
3:  a varname 0.4906111 0.3060961 
4:  a varname 4.7780189 2.9740149 

Wie kann ich Spaltennamen erhalten ('x1', 'x2') in der zweiten Spalte? Ich denke, dass ich rbindlist zu etwas anderem ersetzen muss, aber was? Gibt es eine einfache Lösung?

Antwort

13

Eine alternative Möglichkeit, Ihre eigene Funktion wäre so zu konstruieren, dass Sie diese rbindlist Wrap vermeiden kann (was ich finde, ist nicht notwendig), das gibt Ihnen die Freiheit der Konstruktion Ihrer Funktion wie Sie wollen:

tmp <- function(x) { 
    mm <- colMeans(x) 
    ss=sapply(x, sd) 
    list(names=names(x), mean=mm, sd=ss) 
} 

data[, tmp(.SD), by=group] 
    group names  mean  sd 
1:  a x1 0.4988514 0.2770122 
2:  b x1 0.5246786 0.3014248 
3:  a x2 4.8031253 2.7978401 
4:  b x2 4.9104108 2.9135656 
+0

+1 Dies ist viel eleganter. – juba

4

Sie können Ihre lapply auf names(.SD) statt .SD iterieren. Etwas wie folgt aus:

data <- as.data.table(list(x1 = runif(200), x2 = 10*runif(200), group = factor(sample(letters[1:2])))) 
res <- data[, rbindlist(lapply(names(.SD), function(name) { 
       return(list(name = name, mean = mean(.SD[[name]]), sd = sd(.SD[[name]]))) 
      })) 
      , by = group, .SDcols = c("x1", "x2")] 

Welche gibt:

group name  mean  sd 
1:  b x1 0.5344272 0.2697610 
2:  b x2 4.7628178 2.8313825 
3:  a x1 0.5008916 0.2686017 
4:  a x2 4.6175027 2.8942875 
Verwandte Themen