关于 dplyr:Sum 通过在 R 中聚合复杂的配对名称

Sum by aggregating complex paired names in R

在 R 中,我尝试根据唯一 ID 聚合数据帧,但我需要为 ID 使用某种通配符值。这意味着我有这样的配对名称:

1
2
3
lion_tiger
elephant_lion
tiger_lion

我需要将 lion_tiger 和 tiger_lion ID 相加,因为这对中的顺序无关紧要。

以这个数据框为例:

1
2
df <- data.frame(pair = c("1_3","2_4","2_2","1_2","2_1","4_2","3_1","4_3","3_2"),
             value = c("12","10","19","2","34","29","13","3","14"))

因此,对 ID、"1_2" 和 "2_1" 的值需要在一个新表中求和。然后该新行将显示为:

1
1_2 36

有什么建议吗?虽然我的示例将数字作为配对 ID,但实际上我需要将其读取为文本(如上面的 lion_tiger" 示例)。


我们可以用 _ 拆分"pair"列,然后将 sortpaste 拆分回来,在一个 group by 函数中使用它来获得 sum

1
2
3
tapply(as.numeric(as.character(df$value)),
    sapply(strsplit(as.character(df$pair), '_'), function(x)
     paste(sort(as.numeric(x)), collapse="_")), FUN = sum)

或者另一个选项是 gsubfn

1
2
3
4
5
library(gsubfn)
df$pair <- gsubfn('([0-9]+)_([0-9]+)', ~paste(sort(as.numeric(c(x, y))), collapse='_'),  
      as.character(df$pair))
df$value <- as.numeric(as.character(df$value))
aggregate(value~pair, df, sum)


使用 tidyverse 和 purrrlyr

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
df <- data.frame(name=c("lion_tiger","elephant_lion",
           "tiger_lion"),value=c(1,2,3),stringsAsFactors=FALSE)

require(tidyverse)
require(purrrlyr)
df %>% separate(col = name, sep ="_", c("A","B")) %>%
        by_row(.collate ="rows",
            ..f = function(this_row) {
                  paste0(sort(c(this_row$A, this_row$B)), collapse ="_")
            }) %>%
        rename(sorted =".out") %>%
        group_by(sorted) %>%
        summarize(sum(value))%>%show
## A tibble: 2 x 2
#  sorted `sum(value)`
#  <chr>        <dbl>
#1 elephant_lion   2
#2 lion_tiger      4