R:在按ID分组时按总和汇总包含NA的列值

Sha*_*ath 5 aggregate r plyr dplyr data.table

我有一个数据框

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
Run Code Online (Sandbox Code Playgroud)

虽然我从这篇文章中了解到,但我可以用ID和一列来汇总数据.

我目前正在使用sqldf按ID和类型对行和组进行求和.虽然这对我来说很重要,但它在更大的数据集上却非常缓慢.

    df1 <- sqldf("SELECT ID, Type, Sum(Point_A) as Point_A, Sum(Point_A) as Point_A 
                  FROM df 
                  GROUP BY ID, Type")
Run Code Online (Sandbox Code Playgroud)

请建议使用任何其他可以解决此问题的技术.我已经开始学习dplyr和plyr包了,我发现它非常有趣,但不知道如何在这里应用它.

期望的输出

    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
Run Code Online (Sandbox Code Playgroud)

Ric*_*rta 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
Run Code Online (Sandbox Code Playgroud)


Ste*_*pré 4

使用dplyr

df %>% group_by(ID, Type) %>% summarise_each(funs(sum(., na.rm = T)))
Run Code Online (Sandbox Code Playgroud)

或者

df %>% 
  group_by(ID, Type) %>% 
  summarise(Point_A = sum(Point_A, na.rm = T), 
            Point_B = sum(Point_B, na.rm = T))
Run Code Online (Sandbox Code Playgroud)

或者

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

df %>% 
  group_by(ID, Type) %>% 
  summarise(Point_A = f(Point_A), 
            Point_B = f(Point_B))
Run Code Online (Sandbox Code Playgroud)

这使:

#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
Run Code Online (Sandbox Code Playgroud)