按唯一标识符聚合并将相关值连接成一个字符串[重复]
Posted
技术标签:
【中文标题】按唯一标识符聚合并将相关值连接成一个字符串[重复]【英文标题】:Aggregating by unique identifier and concatenating related values into a string [duplicate] 【发布时间】:2013-05-11 21:10:34 【问题描述】:我认为aggregate
或reshape
可以满足我的需求,但我不太清楚。
我有一个姓名列表 (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
注意
尽管两个结果看起来相同(即当您打印它们时,它们看起来相同),但它们实际上非常不同并且允许不同的功能。
也就是说,使用列表选项(第一个)允许您在原始id
s 上执行功能。
后者可以让您更轻松地显示信息(包括导出到CSV
或excel
),但要对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
【讨论】:
以上是关于按唯一标识符聚合并将相关值连接成一个字符串[重复]的主要内容,如果未能解决你的问题,请参考以下文章