2015-05-14 15 views
5

Mam ramki danych, które dostałem odR: Roll up wartości kolumn zawierających NA poprzez sumy podczas grupowania według identyfikatora

ID <- c("A","A","A","A","B","B","B","B") 
Type <- c(45,45,46,46,45,45,46,46) 
Point_A <- c(10,NA,30,40,NA,80,NA,100) 
Point_B <- c(NA,32,43,NA,65,11,NA,53) 
df <- data.frame(ID,Type,Point_A,Point_B) 

    ID Type Point_A Point_B 
1 A 45  10 NA 
2 A 45  NA 32 
3 A 46  30 43 
4 A 46  40 NA 
5 B 45  NA 65 
6 B 45  80 11 
7 B 46  NA NA 
8 B 46  100 53 

Gdy dowiedziałem się z tego post mogłem zakasać danych z identyfikatora i jednego kolumna.

Obecnie używam sqldf do sumowania wierszy i grup według ID i typu. Chociaż to robi dla mnie zadanie, jest bardzo powolne w większym zbiorze danych.

df1 <- sqldf("SELECT ID, Type, Sum(Point_A) as Point_A, Sum(Point_A) as Point_A 
        FROM df 
        GROUP BY ID, Type") 

Proszę sugerować użycie innych technik, które rozwiązałyby ten problem. Zacząłem uczyć się pakietów plyr i uważam, że jest to bardzo interesujące, ale nie wiem jak to zastosować tutaj.

Pożądany Wyjście

ID Type Point_A Point_B 
1 A 45  10 32 
2 A 46  70 43 
3 B 45  80 76 
4 B 46  100 53 

Odpowiedz

4

Korzystanie dplyr:

df %>% group_by(ID, Type) %>% summarise_each(funs(sum(., na.rm = T))) 

Albo

df %>% 
    group_by(ID, Type) %>% 
    summarise(Point_A = sum(Point_A, na.rm = T), 
      Point_B = sum(Point_B, na.rm = T)) 

Albo

f <- function(x) sum(x, na.rm = T) 

df %>% 
    group_by(ID, Type) %>% 
    summarise(Point_A = f(Point_A), 
      Point_B = f(Point_B)) 

Co daje:

#Source: local data frame [4 x 4] 
#Groups: ID 
# 
# ID Type Point_A Point_B 
#1 A 45  10  32 
#2 A 46  70  43 
#3 B 45  80  76 
#4 B 46  100  53 
+0

Steven, jeszcze raz dziękuję za pomoc w tym pytaniu. Ten pakiet dplyr mnie za każdym razem zadziwia. :-) Jest super szybki na większym zbiorze danych. – Sharath

+1

Dlaczego nie 'summarise_each()' ?? – Arun

+0

@Arun Odpowiadałem na podobne pytania z niewielkimi wariantami i zapomniałem dodać najprostszą metodę. –

9
library(data.table) 

DT <- as.data.table(df) 
DT[, lapply(.SD, sum, na.rm=TRUE), by=list(ID, Type)] 

    ID Type Point_A Point_B 
1: A 45  10  32 
2: A 46  70  43 
3: B 45  80  76 
4: B 46  100  53 
+0

Ricardo, to działa jak uroku :) ale wolę posługiwać dplyr nad data.table ponieważ Obecnie uczę się tego. – Sharath