2015-05-07 4 views
6

Se ho questa listastatistiche riepilogative di più fotogrammi di dati all'interno di un elenco

set.seed(123) 
thelist <- list(a=data.frame(x1=rnorm(10), x2=rnorm(10)), 
       b=data.frame(x1=rnorm(10), x2=rnorm(10)), 
       c=data.frame(x1=rnorm(10), x2=rnorm(10))) 

e volevamo per calcolare la media di ogni colonna all'interno di ogni lista ho potuto farlo con il seguente codice.

sapply(do.call("rbind",thelist),mean) 

Come potevo calcolare la deviazione standard, ancora una volta per ogni colonna all'interno di ogni lista (a: c), in quanto non esiste una funzione equivalente per sd (almeno a mia conoscenza)?

Qualsiasi suggerimento sarebbe apprezzato.

risposta

5

Una base R soluzione sarebbe utilizzare sapply due volte.

Per significare solo che è:

t(sapply(thelist, sapply, mean)) 

Con conseguente

  x1  x2 
a 0.074625644 0.2086220 
b -0.424558873 0.3220446 
c -0.008715537 0.2216860 

Se volete entrambi:

my_summary <- function(x){ 
    c(mean = mean(x), sd = sd(x)) 
} 

as.data.frame(lapply(thelist, sapply, my_summary)) 

Con conseguente:

  a.x1  a.x2  b.x1  b.x2   c.x1  c.x2 
mean 0.07462564 0.208622 -0.4245589 0.3220446 -0.008715537 0.2216860 
sd 0.95378405 1.038073 0.9308092 0.5273024 1.082518163 0.8564451 
+0

fresco, mai visto 'sapply'ing 'sapply' prima! – Frank

+3

Grazie. Alla fine volevo IC. Fornire la tua funzione è stata perfetta. Sono stato in grado di modificarlo in "my_summary <- function (x) { \t c (mean = mean (x), UpperCI = mean (x) + (1.96 * sd (x)), LowerCI = mean (x) + (1.96 * sd (x))) ' }. Funziona alla grande Grazie per il nuovo trucco. –

+1

@ B.Davis Se i tuoi dati sono grandi, meglio calcolare 'mean' e 'sd' solo una volta, come' function (x) {m <- mean (x); s <- sd (x); c (...)} 'Puoi metterli su linee separate invece di usare il punto e virgola, ovviamente. – Frank

4

In primo luogo, mi rendono impilabile facendo il nome in una colonna:

for (i in seq_along(thelist)) thelist[[i]]$dfname <- names(thelist)[i] 

Poi, impilare e prendere i mezzi con data.table:

require(data.table) 
DT <- rbindlist(thelist) 

DT[,lapply(.SD,mean),by=dfname] 

che dà

dfname   x1  x2 
1:  a 0.074625644 0.2086220 
2:  b -0.424558873 0.3220446 
3:  c -0.008715537 0.2216860 

Si potrebbe anche prendere in considerazione la funzione summary, anche se è goffo qui:

DT[,as.list(unlist(lapply(.SD,summary))),by=dfname] 
# dfname x1.Min. x1.1st Qu. x1.Median x1.Mean x1.3rd Qu. x1.Max. x2.Min. x2.1st Qu. x2.Median x2.Mean x2.3rd Qu. x2.Max. 
# 1:  a -1.265 -0.5318 -0.07983 0.074630 0.37800 1.715 -1.9670 -0.32690 0.3803 0.2086  0.6505 1.7870 
# 2:  b -1.687 -1.0570 -0.67700 -0.424600 0.06054 1.254 -0.3805 -0.23680 0.4902 0.3220  0.7883 0.8951 
# 3:  c -1.265 -0.6377 -0.30540 -0.008716 0.56410 2.169 -1.5490 -0.03929 0.1699 0.2217  0.5018 1.5160 

Infine, la copia my old answer, si potrebbe fare il vostro proprio riassunto-stats funzione:

summaryfun <- function(x) list(mean=mean(x),sd=sd(x)) 
DT[,as.list(unlist(lapply(.SD,summaryfun))),by=dfname] 
# dfname  x1.mean  x1.sd x2.mean  x2.sd 
# 1:  a 0.074625644 0.9537841 0.2086220 1.0380734 
# 2:  b -0.424558873 0.9308092 0.3220446 0.5273024 
# 3:  c -0.008715537 1.0825182 0.2216860 0.8564451 
3

È possibile combinare i dati come avete proposto voi stessi e poi aggregato come segue:

thelist_named <- Map(cbind, thelist, nam = names(thelist)) 
thelist_binded <- do.call(rbind, thelist_named) 

Aggregazione Parte:

my_summary <- function(x){ 
    c(mean = mean(x), sd = sd(x)) 
} 
aggregate(.~nam, thelist_binded, my_summary) 

Risultato:

nam  x1.mean  x1.sd x2.mean  x2.sd 
1 a 0.074625644 0.953784051 0.2086220 1.0380734 
2 b -0.424558873 0.930809213 0.3220446 0.5273024 
3 c -0.008715537 1.082518163 0.2216860 0.8564451 
Problemi correlati