按唯一标识符聚合并将相关值连接成一个字符串[重复]

Posted

技术标签:

【中文标题】按唯一标识符聚合并将相关值连接成一个字符串[重复]【英文标题】:Aggregating by unique identifier and concatenating related values into a string [duplicate] 【发布时间】:2013-05-11 21:10:34 【问题描述】:

我认为aggregatereshape 可以满足我的需求,但我不太清楚。

我有一个姓名列表 (brand) 和随附的 ID 号 (id)。该数据是长格式的,因此名称可以有多个 ID。我想按名称 (brand) 进行重复数据删除,并将多个可能的 id 连接成一个由注释分隔的字符串。

例如:

brand            id 
Radioshack       2308
Rag & Bone       4466
Ragu             1830
Ragu             4518
Ralph Lauren     1638
Ralph Lauren     2719
Ralph Lauren     2720
Ralph Lauren     2721
Ralph Lauren     2722 

应该变成:

RadioShack       2308
Rag & Bone       4466
Ragu             1830,4518
Ralph Lauren     1638,2719,2720,2721,2722

我将如何做到这一点?

【问题讨论】:

在你想要的输出中,“Ragu”不应该出现两次,对吧? 对于每个品牌,您希望结果是 list 的 id 还是一个拼凑在一起的字符串? 【参考方案1】:

让我们调用你的 data.frame DF

> aggregate(id ~ brand, data = DF, c)
         brand                           id
1   RadioShack                         2308
2   Rag & Bone                         4466
3         Ragu                   1830, 4518
4 Ralph Lauren 1638, 2719, 2720, 2721, 2722

使用aggregate 的另一种选择是:

result <- aggregate(id ~ brand, data = DF, paste, collapse = ",")

这会产生相同的结果,现在id 不再是list。感谢@Frank 评论。要查看每列的class,请尝试:

> sapply(result, class)
      brand          id 
   "factor" "character"

正如@DavidArenburg 在 cmets 中提到的,另一种选择是使用 toString 函数:

aggregate(id ~ brand, data = DF, toString)

【讨论】:

很奇怪,R 不允许我输出这个 data.frame...我想是因为 id 是一个列表。如何导出到 CSV? @Jilber 你的“id”输出列的类应该是“字符”(不是列表),我认为,因为 OP 想要导出数据框。 +1。我喜欢这个解决方案,供我自己使用。不过,对于 OP 的问题,我认为您可能希望将其更改为 aggregate(id~brand,paste,collapse=",",data=df) 或类似名称。 很可能值得一提aggregate(id ~ brand, DF, toString) 如果我想做同样的事情但只针对特定价值会发生什么?我的意思是,在你的例子中只有id==2308【参考方案2】:

data.table 中的一行很干净

library(data.table)
setDT(DF)

两个选项:

结果为列表

DF[ , .(id = list(id)), by = brand]
          brand                       id
1:   RadioShack                     2308
2:   Rag & Bone                     4466
3:         Ragu                1830,4518
4: Ralph Lauren 1638,2719,2720,2721,2722
> 

结果为字符串

DF[ , .(id = paste(id, collapse=",")), by = brand]
          brand                       id
1:   RadioShack                     2308
2:   Rag & Bone                     4466
3:         Ragu                1830,4518
4: Ralph Lauren 1638,2719,2720,2721,2722

注意

尽管两个结果看起来相同(即当您打印它们时,它们看起来相同),但它们实际上非常不同并且允许不同的功能。

也就是说,使用列表选项(第一个)允许您在原始ids 上执行功能。

后者可以让您更轻松地显示信息(包括导出到CSVexcel),但要对id 进行操作则需要将它们拼接回去。

【讨论】:

谢谢! list(list(id)) 有效,但为什么呢? @LauriK, list(list(id)) 与答案中的第一个选项相同。唯一的区别是列表中的名称是否明确给出。外部list, data.table 将翻译成“列”的意思(因为所有的 data.tables 和 data.frames 实际上只是列的列表)。内部list表示每个单元格中的值将是一个列表 谢谢!我正在使用paste(id, sep = ",") 并最终得到未汇总的结果。事实证明,我需要改用paste(id, collapse = ",")【参考方案3】:

或者使用dplyr:

library(dplyr)
DF %>%
  group_by(brand) %>%
  summarise(id = paste(id, collapse = ","))

DF 是您的 data.frame 的名称。

【讨论】:

这将使汇总列成为逗号分隔的字符串类型。不是向量... 不,就像在其他答案中一样,结果是一个data.frame,带有一个名为id 的向量,属于character 类,包含id 的字符串,根据需要用逗号分隔这个问题。 is.vector(DF$id) 返回TRUE。如果您对此方法有任何疑问,请考虑将其作为新问题发布。 library(dplyr) DFNew% group_by(brand) %>% summarise(id=unique(list(id))) 这对我有用 @SamFirke,您能否建议我如何使用您的解决方案仅粘贴 id 的唯一值,而 id 的重复值对应于 brand?谢谢! 尝试添加unique,改成paste(unique(id), collapse = ",") - 如果不这样做,值得发布一个新问题。【参考方案4】:

这是base R中的信息:

myby <- by(df$id,df$brand,function(x)paste(x,collapse=","))

“by”对象的格式很奇怪。您可以使用data.frame(id=c(myby)),品牌将成为行名:

#                                    id
# RadioShack                       2308
# Rag & Bone                       4466
# Ragu                        1830,4518
# Ralph Lauren 1638,2719,2720,2721,2722

或者,如果您加载 data.table 包,这将起作用:

dt <- data.table(df)
dt[,paste(id,collapse=","),by=brand]
#           brand                       V1
# 1:   RadioShack                     2308
# 2:   Rag & Bone                     4466
# 3:         Ragu                1830,4518
# 4: Ralph Lauren 1638,2719,2720,2721,2722

【讨论】:

以上是关于按唯一标识符聚合并将相关值连接成一个字符串[重复]的主要内容,如果未能解决你的问题,请参考以下文章

Pandas groupby,在字符串变量上聚合并向上移动空单元格

如何将连接值分组并聚合为字符串[重复]

查找唯一标识符重复的每个字段的最大序列号

$group 按 MongoDb 聚合中的每个唯一字符串

mongoDB聚合将相似的文档彼此相邻分组

Java中生成的UUID(全局唯一标识符-----(唯一)-------)