将每列中的多列折叠/合并/汇总为单个逗号分隔的字符串

时间:2020-02-14 20:29:30

标签: r aggregate

这是发布Collapse / concatenate / aggregate a column to a single comma separated string within each group

的扩展名

目标:根据一个分组变量汇总多个列,并通过选择的分隔符分隔各个值。

可复制的示例:

data <- data.frame(A = c(rep(111, 3), rep(222, 3)), B = c(rep(c(100), 3), rep(200,3)), C = rep(c(1,2,NA),2), D = c(15:20), E = rep(c(1,NA,NA),2))
data
    A   B  C  D  E
1 111 100  1 15  1
2 111 100  2 16 NA
3 111 100 NA 17 NA
4 222 200  1 18  1
5 222 200  2 19 NA
6 222 200 NA 20 NA

A是分组变量,但B仍显示在整体结果中(B取决于我的应用程序中的A),而C,D和E是要折叠成单独的character字符串的变量。

所需的输出

    A   B  C    D         E
1 111 100  1,2  15,16,17  1
2 222 100  1,2  18,19,20  1    

我对R并没有太多的经验。我确实尝试将G. Grothendieck发布的解决方案扩展到链接的帖子中,以满足我的要求,但不能完全满足于多栏目的。

要获得所需的输出,什么是正确的实现方式?

在尝试过程中,我特别关注了group_bysummarise_allaggregate。它们是一团糟,所以我认为它甚至对显示都没有帮助。

编辑: 发布的解决方案非常适合显示期望的结果! 为了继续为那些发现它的人提高价值。

用户如何选择自己的分隔字符。 例如'-''\n' @akrun和@tmfmnk当前的解决方案均产生列表,而不是串联的character字符串。如果我说错了,请纠正我。

data$D
[1] 15 16 17 18 19 20
> data$A
[1] 111 111 111 222 222 222
> data$B
[1] 100 100 100 200 200 200
> data$C
[1]  1  2 NA  1  2 NA
> data$D
[1] 15 16 17 18 19 20
> data$E
[1]  1 NA NA  1 NA NA

2 个答案:

答案 0 :(得分:2)

我们可以按'A','B'分组,并使用summarise_atpaste所有非NA元素

library(dplyr)
data %>% 
    group_by(A, B) %>%
    summarise_at(vars(-group_cols()), ~ toString(.[!is.na(.)]))
# A tibble: 2 x 5
# Groups:   A [2]
#      A     B C     D          E    
#  <dbl> <dbl> <chr> <chr>      <chr>
#1   111   100 1, 2  15, 16, 17 1    
#2   222   200 1, 2  18, 19, 20 1   

如果我们需要传递自定义分隔符,请使用pastestr_c

library(stringr)
data %>% 
    group_by(A, B) %>%
    summarise_at(vars(-group_cols()), ~ str_c(.[!is.na(.)], collapse="_"))

或将base Raggregate一起使用

aggregate(. ~ A + B, data, FUN = function(x) 
      toString(x[!is.na(x)]), na.action = NULL)

答案 1 :(得分:1)

使用dplyr,您可以执行以下操作:

data %>%
 group_by(A, B) %>%
 summarise_all(~ toString(na.omit(.)))

      A     B C     D          E    
  <dbl> <dbl> <chr> <chr>      <chr>
1   111   100 1, 2  15, 16, 17 1    
2   222   200 1, 2  18, 19, 20 1