我有这样的NA数据,
D1 pobox HID S1 locID UID C1 C2 C3 C4 C5 C6
1 1 Box 134 2 1 -9 4 NA NA NA NA NA NA
2 1 Box 134 2 1 2 4 3 99 10 10 0 0
3 1 Box 35 3 NA NA 2 NA NA NA NA NA NA
4 1 Box 169 7 NA NA 3 NA NA NA NA NA NA
5 2 Box 115 12 2 -9 4 NA NA NA NA NA NA
6 2 Box 115 12 2 2 4 0 7 90 10 NA 0
7 2 Box 126 16 3 -9 3 0 0 0 0 0 0
8 3 Box 72 17 NA NA 4 NA NA NA NA NA NA
9 3 Box 54 19 4 -9 4 0 0 0 0 0 0
10 3 Box 71 22 NA NA 2 NA NA NA NA NA NA
11 4 Box 61 23 5 -9 4 NA NA NA NA NA NA
12 4 Box 61 23 5 2 4 0 100 0 NA 0 0
13 4 Box 61 23 5 12 4 0 15 0 10 NA 0
14 4 Box 4 27 6 -9 4 0 0 0 0 0 0
15 4 Box 64 29 NA NA 3 NA NA NA NA NA NA
16 4 Box 144 30 NA NA 2 NA NA NA NA NA NA
我想通过D1,pobox,HID,S1,UID聚合(Say,sum)C1,C2,C3,C4,C5,C6 我想得到的是这样的数据,当至少一个条目有数字时忽略NA,并且当所有条目都是NA时保持NA。
D1 pobox HID S1 UID V1 V2 V3 V4 V5 V6
1: 1 Box 134 2 1 4 3 99 10 10 0 0
2: 1 Box 35 3 NA 2 NA NA NA NA NA NA
3: 1 Box 169 7 NA 3 NA NA NA NA NA NA
4: 2 Box 115 12 2 4 0 7 90 10 NA 0
5: 2 Box 126 16 3 3 0 0 0 0 0 0
6: 3 Box 72 17 NA 4 NA NA NA NA NA NA
7: 3 Box 54 19 4 4 0 0 0 0 0 0
8: 3 Box 71 22 NA 2 NA NA NA NA NA NA
9: 4 Box 61 23 5 4 0 115 0 10 0 0
10: 4 Box 4 27 6 4 0 0 0 0 0 0
11: 4 Box 64 29 NA 3 NA NA NA NA NA NA
12: 4 Box 144 30 NA 2 NA NA NA NA NA NA
我试过
聚合(cbind(C1,C2,C3,C4,C5,C6)~D1 + pobox + HID + S1 + UID,data = test,sum,na.action = na.pass,na.rm = TRUE)
D1 pobox HID S1 UID C1 C2 C3 C4 C5 C6
1 2 Box 126 16 3 3 0 0 0 0 0 0
2 1 Box 134 2 1 4 3 99 10 10 0 0
3 2 Box 115 12 2 4 0 7 90 10 0 0
4 3 Box 54 19 4 4 0 0 0 0 0 0
5 4 Box 61 23 5 4 0 115 0 10 0 0
6 4 Box 4 27 6 4 0 0 0 0 0 0
这不起作用, 接下来,我尝试使用doBy包
进行summaryBysummaryBy(C1 + C2 + C3 + C4 + C5~D1 + pobox + HID + S1 + UID,FUN = sum,data = test,na.rm = TRUE,na.pass = TRUE,keep.names = TRUE )
这导致所有NA得到1
D1 pobox HID S1 UID C1 C2 C3 C4 C5
1 1 Box 134 2 1 4 4 100 11 11 1
2 1 Box 169 7 NA 3 1 1 1 1 1
3 1 Box 35 3 NA 2 1 1 1 1 1
4 2 Box 115 12 2 4 1 8 91 11 1
5 2 Box 126 16 3 3 1 1 1 1 1
6 3 Box 54 19 4 4 1 1 1 1 1
7 3 Box 71 22 NA 2 1 1 1 1 1
8 3 Box 72 17 NA 4 1 1 1 1 1
9 4 Box 144 30 NA 2 1 1 1 1 1
10 4 Box 4 27 6 4 1 1 1 1 1
11 4 Box 61 23 5 4 1 116 1 11 1
12 4 Box 64 29 NA 3 1 1 1 1 1
尝试过data.table包
SUMT< -DT [,列表(总和(C1),和(C2),和(C3),和(C4),和(C 5),和(C6)),由=列表(D1,POBOX, HID,S1,UID)]
D1 pobox HID S1 UID V1 V2 V3 V4 V5 V6
1: 1 Box 134 2 1 4 NA NA NA NA NA NA
2: 1 Box 35 3 NA 2 NA NA NA NA NA NA
3: 1 Box 169 7 NA 3 NA NA NA NA NA NA
4: 2 Box 115 12 2 4 NA NA NA NA NA NA
5: 2 Box 126 16 3 3 0 0 0 0 0 0
6: 3 Box 72 17 NA 4 NA NA NA NA NA NA
7: 3 Box 54 19 4 4 0 0 0 0 0 0
8: 3 Box 71 22 NA 2 NA NA NA NA NA NA
9: 4 Box 61 23 5 4 NA NA NA NA NA NA
10: 4 Box 4 27 6 4 0 0 0 0 0 0
11: 4 Box 64 29 NA 3 NA NA NA NA NA NA
12: 4 Box 144 30 NA 2 NA NA NA NA NA NA
现在,使用na.rm = TRUE,
SUMT< -DT [,列表(总和(C1,na.rm = TRUE),和(C2,na.rm = TRUE),和(C3,na.rm = TRUE),和(C4,呐。 RM = TRUE),和(C5,na.rm = TRUE),和(C6,na.rm = TRUE)),通过列表=(D1,POBOX,HID,S1,UID)]
D1 pobox HID S1 UID V1 V2 V3 V4 V5 V6
1: 1 Box 134 2 1 4 3 99 10 10 0 0
2: 1 Box 35 3 NA 2 0 0 0 0 0 0
3: 1 Box 169 7 NA 3 0 0 0 0 0 0
4: 2 Box 115 12 2 4 0 7 90 10 0 0
5: 2 Box 126 16 3 3 0 0 0 0 0 0
6: 3 Box 72 17 NA 4 0 0 0 0 0 0
7: 3 Box 54 19 4 4 0 0 0 0 0 0
8: 3 Box 71 22 NA 2 0 0 0 0 0 0
9: 4 Box 61 23 5 4 0 115 0 10 0 0
10: 4 Box 4 27 6 4 0 0 0 0 0 0
11: 4 Box 64 29 NA 3 0 0 0 0 0 0
12: 4 Box 144 30 NA 2 0 0 0 0 0 0
答案 0 :(得分:3)
这是一个dplyr选项:
library(dplyr)
test %>%
group_by(D1,pobox,HID,S1,UID) %>%
summarise_each(funs(
if(all(is.na(.))) NA else sum(., na.rm = TRUE)),
num_range("C", 1:6)) # could add %>% ungroup() if necessary
#Source: local data frame [12 x 11]
#Groups: D1, pobox, HID, S1
#
# D1 pobox HID S1 UID C1 C2 C3 C4 C5 C6
#1 1 Box 134 2 1 4 3 99 10 10 0 0
#2 1 Box 169 7 NA 3 NA NA NA NA NA NA
#3 1 Box 35 3 NA 2 NA NA NA NA NA NA
#4 2 Box 115 12 2 4 0 7 90 10 NA 0
#5 2 Box 126 16 3 3 0 0 0 0 0 0
#6 3 Box 54 19 4 4 0 0 0 0 0 0
#7 3 Box 71 22 NA 2 NA NA NA NA NA NA
#8 3 Box 72 17 NA 4 NA NA NA NA NA NA
#9 4 Box 144 30 NA 2 NA NA NA NA NA NA
#10 4 Box 4 27 6 4 0 0 0 0 0 0
#11 4 Box 61 23 5 4 0 115 0 10 0 0
#12 4 Box 64 29 NA 3 NA NA NA NA NA NA
以上是对上述代码的一点修改:
test %>%
group_by(D1,pobox,HID,S1,UID) %>%
summarise_each(funs(sum(., na.rm = !all(is.na(.)))), num_range("C", 1:6))
这样您可以根据每个组中的值定义na.rm =
参数(如果不所有值都是NA则为TRUE,否则为FALSE)。
这是一个类似的data.table方法:
library(data.table)
setDT(test)[,lapply(.SD, function(x) sum(x, na.rm = !all(is.na(x)))),
.SDcols = paste0("C", 1:6), by = .(D1,pobox,HID,S1,UID)]
# D1 pobox HID S1 UID C1 C2 C3 C4 C5 C6
#1: 1 Box 134 2 1 4 3 99 10 10 0 0
#2: 1 Box 35 3 NA 2 NA NA NA NA NA NA
#3: 1 Box 169 7 NA 3 NA NA NA NA NA NA
#4: 2 Box 115 12 2 4 0 7 90 10 NA 0
#5: 2 Box 126 16 3 3 0 0 0 0 0 0
#6: 3 Box 72 17 NA 4 NA NA NA NA NA NA
#7: 3 Box 54 19 4 4 0 0 0 0 0 0
#8: 3 Box 71 22 NA 2 NA NA NA NA NA NA
#9: 4 Box 61 23 5 4 0 115 0 10 0 0
#10: 4 Box 4 27 6 4 0 0 0 0 0 0
#11: 4 Box 64 29 NA 3 NA NA NA NA NA NA
#12: 4 Box 144 30 NA 2 NA NA NA NA NA NA
答案 1 :(得分:0)
这是使用plyr
包
# recreate Data (need to wrap pobox in "s)
# use clipboard on Windows
data <- read.table(pipe("pbpaste"),header = T,stringsAsFactors = T)
library(plyr)
# create conditional sum function
sum_rmna <- function(x) {
if(all(is.na(x))){r <- sum(x)}
if(!(all(is.na(x)))){r <- sum(x,na.rm = TRUE)}
return(r)}
# use ddply from plyr package
cdata <- ddply(data,c("D1","pobox","HID","S1"),summarise,
V1 = sum_rmna(C1),
V2 = sum_rmna(C2),
V3 = sum_rmna(C3),
V4 = sum_rmna(C4),
V5 = sum_rmna(C5),
V6 = sum_rmna(C6))
这将返回
> cdata
D1 pobox HID S1 V1 V2 V3 V4 V5 V6
1 1 Box 134 2 1 3 99 10 10 0 0
2 1 Box 169 7 NA NA NA NA NA NA NA
3 1 Box 35 3 NA NA NA NA NA NA NA
4 2 Box 115 12 2 0 7 90 10 NA 0
5 2 Box 126 16 3 0 0 0 0 0 0
6 3 Box 54 19 4 0 0 0 0 0 0
7 3 Box 71 22 NA NA NA NA NA NA NA
8 3 Box 72 17 NA NA NA NA NA NA NA
9 4 Box 144 30 NA NA NA NA NA NA NA
10 4 Box 4 27 6 0 0 0 0 0 0
11 4 Box 61 23 5 0 115 0 10 0 0
12 4 Box 64 29 NA NA NA NA NA NA NA