如何在R中按名称聚合两列?

如何在R中按名称聚合两列?,r,merge,aggregate,na,R,Merge,Aggregate,Na,我得到了一个数据帧: a <- c('A','A','B','B','A') b <- c(1,1,1,1,2) c <- c(NA,60,NA,100,NA) d <- c(10,NA,10,NA,100) frame <- data.frame(a,b,c,d) > frame a b c d 1 A 1 NA 10 2 A 1 60 NA 3 B 1 NA 10 4 B 1 100 NA 5 A 2 NA 10

我得到了一个数据帧:

a <- c('A','A','B','B','A')
b <- c(1,1,1,1,2)
c <- c(NA,60,NA,100,NA)
d <- c(10,NA,10,NA,100)

frame <- data.frame(a,b,c,d)

> frame
  a  b   c  d
1 A  1  NA  10
2 A  1  60  NA
3 B  1  NA  10
4 B  1 100  NA
5 A  2  NA  100

我尝试了几种方法,比如dplyr中的aggregate()和group,但不知怎的,它从来都不起作用。我想NA是个问题

对于
aggregate
,我们可能需要使用
na.action

aggregate(.~ a + b, frame, sum, na.rm = TRUE, na.action = 'na.pass')
#   a b   c   d
#1 A 1  60  10
#2 B 1 100  10
#3 A 2   0 100

如果我们打算对行进行子集划分

library(dplyr)
frame %>% 
    group_by(a, b) %>%
    mutate_at(vars(-group_cols()), ~ .[order(is.na(.))]) %>% 
    slice(1)
# A tibble: 3 x 4
# Groups:   a, b [3]
#  a         b     c     d
#  <fct> <dbl> <dbl> <dbl>
#1 A         1    60    10
#2 A         2    NA   100
#3 B         1   100    10
库(dplyr)
帧%>%
(a,b)组%>%
在(vars(-groupcols()),~[顺序(is.na(.))]%>%处突变
切片(1)
#一个tibble:3x4
#组:a、b[3]
#a、b、c、d
#     
#16010
#2 A 2 NA 100
#3 B 1100 10

除了使用
aggreate()
by外,您还可以使用以下代码来实现:

aggregate(frame[-(1:2)], frame[1:2], sum, na.rm = TRUE)
以致

> aggregate(frame[-(1:2)], frame[1:2], sum, na.rm = TRUE)
  a b   c   d
1 A 1  60  10
2 B 1 100  10
3 A 2   0 100
使用
data.table
hablar::sum

库(data.table)
setDT(frame)[,(c=as.numeric(hablar::sum_uz(c)),
d=作为数字(hablar::sum_ud)),(a,b)]
#>a、b、c、d
#>1:16010
#>2:B110010
#>3:A 2NA 100
或者在
base
中,我们可以定义自己的函数,并将其与
aggregate
一起使用,如akrun在其回答中所示:


sum\up>使用
dplyr
tidyr
可以将数据重塑为长格式,过滤NA行,然后重塑为宽格式。这基本上结合了c和d值,并保留了c列中的
NA

库(dplyr)
图书馆(tidyr)
帧%>%
枢轴长度(c:d)%>%
过滤器(!is.na(值))%>%
排列(名称)%%>%
枢轴(名称从=名称)
#>#tibble:3 x 4
#>a、b、c、d
#>      
#>16010
#>2B110010
#>3 A 2 NA 100

IMO的一个小麻烦是,与之前的
tidyr::spread
不同,
tidyr::pivot\u wide
保持数据的顺序;如果你不调用
arrange
,你会得到d列,然后是c列,因为过滤后的观察顺序。

起初我想知道为什么会这么复杂,但是这个
dplyr
解决方案似乎是解决方案中唯一返回
NA
的解决方案,就像问题中预期的解决方案一样。
> aggregate(frame[-(1:2)], frame[1:2], sum, na.rm = TRUE)
  a b   c   d
1 A 1  60  10
2 B 1 100  10
3 A 2   0 100