2015-09-04 13 views
7

Chcę zgrupować data.table na podstawie wartości kolumny zakres wartość, w jaki sposób mogę to zrobić z biblioteki dplyr?Jak wykonać grupowanie zakresów w kolumnie za pomocą dplyr?

Na przykład, moja tabela danych jest jak poniżej:

library(data.table) 
library(dplyr) 
DT <- data.table(A=1:100, B=runif(100), Amount=runif(100, 0, 100)) 

Teraz chcę grupy DT do 20 grup w przedziale 0,05 kolumnie B, i policzyć, ile wierszy są w każdej grupie. np. wszelkie wiersze z wartością kolumny B w zakresie [0, 0,05] utworzą grupę; wszystkie wiersze z wartością kolumny B w zakresie [0,05, 0,1) utworzą inną grupę i tak dalej. Czy istnieje skuteczny sposób wykonywania tej funkcji grupowej?

Dziękuję bardzo.

----------------------------- Więcej pytań na temat odpowiedzi akrun. Dzięki akrun za odpowiedź. Dostałem nowe pytanie o funkcję "cut". Jeśli moja DT jest jak poniżej:

DT <- data.table(A=1:10, B=c(0.01, 0.04, 0.06, 0.09, 0.1, 0.13, 0.14, 0.15, 0.17, 0.71)) 

za pomocą następującego kodu:

DT %>% 
    group_by(gr=cut(B, breaks= seq(0, 1, by = 0.05), right=F)) %>% 
    summarise(n= n()) %>% 
    arrange(as.numeric(gr)) 

Spodziewam się, aby zobaczyć wyniki tak:

  gr n 
1 [0,0.05) 2 
2 [0.05,0.1) 2 
3 [0.1,0.15) 3 
4 [0.15,0.2) 2 
5 [0.7,0.75) 1 

ale wynik mam to tak :

  gr n 
1 [0,0.05) 2 
2 [0.05,0.1) 2 
3 [0.1,0.15) 4 
4 [0.15,0.2) 1 
5 [0.7,0.75) 1 

Wygląda jak t wartość 0,15 nie jest poprawnie przydzielona. Jakieś przemyślenia na ten temat?

+0

Możesz użyć 'cut' – akrun

+0

Jeśli początkowym obiektem jest data.table, możemy użyć metod data.table' DT [, .N,. (Gr = cut (B, breaks = seq (0, max (B), o = 0.05))]] ' – akrun

+0

Fyi, miło używać' set.seed' przy tworzeniu przypadkowych danych przykładowych, więc wszyscy patrzymy na te same dane. – Frank

Odpowiedz

13

Możemy użyć cut, aby wykonać grupowanie. Tworzymy kolumnę "gr" w ramach group_by, używamy summarise do tworzenia liczby elementów w każdej grupie (n()) i zamawiamy wyjście (arrange) na podstawie "gr".

library(dplyr) 
DT %>% 
    group_by(gr=cut(B, breaks= seq(0, 1, by = 0.05))) %>% 
    summarise(n= n()) %>% 
    arrange(as.numeric(gr)) 

Jako początkowy przedmiot jest data.table, można to zrobić za pomocą data.table metod (wliczone @ sugestią Franka używać keyby)

library(data.table) 
DT[,.N , keyby = .(gr=cut(B, breaks=seq(0, 1, by=0.05)))] 

EDIT:

W oparciu o aktualizacji w poście PO moglibyśmy odjąć niewielką liczbę na seq

lvls <- levels(cut(DT$B, seq(0, 1, by =0.05))) 
DT %>% 
    group_by(gr=cut(B, breaks= seq(0, 1, by = 0.05) - 
       .Machine$double.eps, right=FALSE, labels=lvls)) %>% 
    summarise(n=n()) %>% 
    arrange(as.numeric(gr)) 
#   gr n 
#1 (0,0.05] 2 
#2 (0.05,0.1] 2 
#3 (0.1,0.15] 3 
#4 (0.15,0.2] 2 
#5 (0.7,0.75] 1 
+1

@Frank Dzięki, zmieniłem to. – akrun

+0

Cześć akrun, dodam nowe pytanie w tym poście, ponieważ jest to część mojego problemu. Po ich rozwiązaniu przyjmuję rozwiązanie. Dzięki. – Carter

+0

@Carter Dzięki, pomyślałem, że zadajesz zupełnie nowe pytanie. – akrun

Powiązane problemy