2015-04-14 33 views
17

Birden çok işlevi data.table'un birden çok sütununa uygulamak için çalışıyorum. Örnek:data.table R - birden çok işlevi birden fazla sütuna uygulama

DT <- data.table("a"=1:5, 
       "b"=2:6, 
       "c"=3:7) 

ı ortalama ve sütunlar a ve b ortancasını almak istiyorum diyelim.

stats <- DT[,.(mean_a=mean(a), 
       median_a=median(a), 
       mean_b=mean(b), 
       median_b=median(b))] 

Ama yol çok tekrarlanan geçerli: Bu çalışır. .SDcols ve lapply'u kullanarak benzer bir sonuç elde etmenin iyi bir yolu var mı?

+1

Neden özel fonksiyonu içine işlevlerini koymak ve öyle hitap? – A5C1D2H2I1M1N2O1R2T1

+3

Veya "dcast" in aynı anda birden çok sütun kümesini işleyebildiği "data.table" geliştirme sürümüne bakın. – A5C1D2H2I1M1N2O1R2T1

+2

Bu, 'dplyr' summarise_each (DT, eğriler (ortalama, medyan), 1: 2)' – akrun

cevap

18

Bunu normalde ediyorum:

my.summary = function(x) list(mean = mean(x), median = median(x)) 

DT[, unlist(lapply(.SD, my.summary)), .SDcols = c('a', 'b')] 
#a.mean a.median b.mean b.median 
#  3  3  4  4 
+1

Benzer bir fikrim vardı ama OP'nin bir vektör yerine bir data.table çıkışı istediğini düşündüğü bir DT ', as.list (liste (lapply (.SD, my.summary))), .SDcols = c ('a' , 'b')] ' – akrun

+5

Ayrıca muhtemelen 'my.summary = function (x) c' yi de basitleştirebilirsiniz (ortalama = ortalama (x), medyan = medyan (x)); DT [, sapply (.SD, my.summary), .SDcols = a: b] ' –

+2

Ama bu kategori ' DT [, as.list (liste dışı) (lapply (. SD, my.summary))), = kategori , .SDcols = c ('a', 'b')] ' Bu, her özeti yaparak ve daha sonra katılarak daha uzun sürmektedir. Bunu yapmanın daha hızlı bir yolu var mı? @akrun sütununda yaklaşık 1,5 milyon grup var – sriramn

7

Bu biraz sakar ama data.table ile işi yapar:

funcs = c('median', 'mean', 'sum') 

m = DT[, lapply(.SD, function(u){ 
     sapply(funcs, function(f) do.call(f,list(u))) 
    })][, t(.SD)] 
colnames(m) = funcs 

# median mean sum 
#a  3 3 15 
#b  4 4 20 
#c  5 5 25 
+0

Güzel, teşekkürler. – paljenczy

+0

Rica ederim! –

+1

Sadece bir 't()' çağrısı için yeni bir bağımlılık eklemek biraz yük olarak görünüyor, neden zincirleme kullanılmıyor? 'm = DT [...] [, t (.SD)]'. Bence daha okunabilir. – jangorecki

İlgili konular