2015-04-14 17 views
17

Próbuję zastosować wiele funkcji do wielu kolumn data.table. Przykład:data.table w R - zastosowanie wielu funkcji do wielu kolumn

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

Powiedzmy, że chcesz uzyskać średnią i medianę kolumn a i b. to działa:

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

Ale to jest zbyt monotonne. Czy istnieje dobry sposób na osiągnięcie podobnego wyniku przy użyciu .SDcols i lapply?

+1

Dlaczego nie umieścić funkcje do funkcji niestandardowej i nazwać? – A5C1D2H2I1M1N2O1R2T1

+3

A może spojrzeć na wersję rozwojową "data.table", gdzie 'dcast' może obsłużyć wiele agregacji kolumn naraz. – A5C1D2H2I1M1N2O1R2T1

+2

Może to być łatwiejsze za pomocą 'dplyr'' summarise_each (DT, funs (średnia, mediana), 1: 2) ' – akrun

Odpowiedz

18

bym normalnie to zrobić:

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

Miałem podobny pomysł, ale myślałem, że OP chce mieć wyjście danych.table zamiast wektora 'DT [, as.list (unlist (lapply (.SD, my.summary))), .SDcols = c (" a " , 'b')] ' – akrun

+5

Można również prawdopodobnie uprościć do' my.summary = funkcja (x) c (średnia = średnia (x), mediana = mediana (x)); DT [, sapply (.SD, my.summary), .SDcols = a: b] ' –

+2

Ale to wydaje się być strasznie wolne, jeśli dodaję grupę według kategorii ' DT [, as.list (unlist (lapply (. SD, my.summary))), by = category, .SDcols = c ("a", "b")] ' To zajmuje znacznie więcej czasu niż wykonanie każdego podsumowania indywidualnie, a następnie dołączenie. Szybszy sposób to zrobić? Mam około 1,5 miliona grup w kolumnie kategorii @akrun – sriramn

7

To jest trochę niezdarny, ale spełnia swoje zadanie z data.table:

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

Fajnie, dziękuję. – paljenczy

+0

Nie ma za co! –

+1

Dodanie nowej zależności tylko dla jednego wywołania 't()' wydaje się być nieco zbyteczne, dlaczego nie użyć łączenia? 'm = DT [...] [, t (.SD)]'. Myślę, że jest również bardziej czytelny. – jangorecki

Powiązane problemy