【问题标题】:Group rows if the value of a column appears in the other column如果列的值出现在另一列中,则对行进行分组
【发布时间】:2019-12-01 00:25:52
【问题描述】:

我有一个要根据列中的值进行分组的数据框。

诀窍是,如果值已经出现在我分组依据的列中,则需要合并一些行。

例如:

df <- data.frame(col1 = c("R1", "R2", "R2", "R2", "R2", "R4", "R5", "R5", "R5"),
                 col2 = c("R10", "R4", "R5", "R6", "R7", "R5", "R6", "R7", "R9"), stringsAsFactors = FALSE)

df2 <- aggregate(col2 ~ col1, df, FUN = function(x) paste(unique(x), collapse = ", "))

> df
  col1 col2
1   R1  R10
2   R2   R4
3   R2   R5
4   R2   R6
5   R2   R7
6   R4   R5
7   R5   R6
8   R5   R7
9   R5   R9

> df2
  col1           col2
1   R1            R10
2   R2 R4, R5, R6, R7
3   R4             R5
4   R5     R6, R7, R9

R10 将在 R1 组(第 1 行)中

R4、R5、R6 和 R7 将在 R2 组中(第 2 到 5 行) R5 将在 R4 组(第 6 行)

R6、R7 和 R9 将属于 R5 组(行:7 到 9)

但是 R4 和 R5 已经在 R2 中,所以它会留在 R2 中。 对于原本分配给R5的R9,需要归入R2。

所以期望的结果是:

> df3
  col1               col2
1   R1                R10
2   R2 R4, R5, R6, R7, R9

或者最好:

1 col1 col2
2   R1  R10
3   R2   R4
4   R2   R5
5   R2   R6
6   R2   R7
7   R2   R9

【问题讨论】:

标签: r dplyr data.table


【解决方案1】:

一个选项是 replace 基于 intersecting 元素的值,然后执行 aggregate

i1 <- df$col1 %in% df$col2
df$col1[i1] <- df$col1[match(df$col1[inds], df$col2)]
aggregate(col2 ~ col1, unique(df), FUN = toString)
#   col1               col2
#1   R1                R10
#2   R2 R4, R5, R6, R7, R9

或者tidyverse

library(dplyr)
library(stringr)
df %>% 
    group_by(col1 = case_when(col1 %in%  intersect(col1, col2) ~ "R2", 
                   TRUE ~ col1)) %>% 
    distinct %>% 
    summarise(col2 = toString(col2))
# A tibble: 2 x 2
#  col1  col2              
#  <chr> <chr>             
#1 R1    R10               
#2 R2    R4, R5, R6, R7, R9

【讨论】:

  • 谢谢阿克伦。在实际数据集中,我有更多行和更多组要定义,所以如果可能的话,我不想硬编码R2。有没有办法替换这条线?
  • 谢谢,这适用于这个例子——在我得到的实际数据集中,这仍然会产生一些重叠的组,但我想我可以从这里开始工作。
【解决方案2】:

一个以 R 为基数的选项可以是

inds <- df$col1 %in% df$col2
df$col1[inds] <- df$col1[match(df$col1[inds], df$col2)]

然后我们只能取unique 数据帧的值

unique(df)

#  col1 col2
#1   R1  R10
#2   R2   R4
#3   R2   R5
#4   R2   R6
#5   R2   R7
#9   R2   R9

或者如果你想要逗号分隔的字符串

aggregate(col2 ~ col1, unique(df), toString)

#  col1               col2
#1   R1                R10
#2   R2 R4, R5, R6, R7, R9

【讨论】:

    猜你喜欢
    • 2022-08-17
    • 2020-08-21
    • 2012-11-06
    • 2021-10-30
    • 2017-04-01
    • 2019-02-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多