通过唯一标识符进行聚合并将相关值连接到字符串中

roo*_*ody 51 aggregate r concatenation

我有一个需要,我想可以满足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 
Run Code Online (Sandbox Code Playgroud)

应成为:

RadioShack       2308
Rag & Bone       4466
Ragu             1830,4518
Ralph Lauren     1638,2719,2720,2721,2722
Run Code Online (Sandbox Code Playgroud)

我怎么做到这一点?

Jil*_*ina 60

我们来调用你的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
Run Code Online (Sandbox Code Playgroud)

另一种替代方案aggregate是:

result <- aggregate(id ~ brand, data = DF, paste, collapse = ",")
Run Code Online (Sandbox Code Playgroud)

这将产生相同的结果,现在id不是list了.感谢@Frank评论.要查看class每列的内容,请尝试:

> sapply(result, class)
      brand          id 
   "factor" "character"
Run Code Online (Sandbox Code Playgroud)

正如@DavidArenburg在评论中所提到的,另一种选择是使用该toString功能:

aggregate(id ~ brand, data = DF, toString)
Run Code Online (Sandbox Code Playgroud)

  • +1.我喜欢这个解决方案,供我自己使用.我想你可能想把它改成`聚合(id~cold,paste,collapse =",",data = df)`或类似的OP的问题. (2认同)

Ric*_*rta 37

干净利落的一条线路 data.table

library(data.table)
setDT(DF)
Run Code Online (Sandbox Code Playgroud)

两种选择:

结果列表

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
> 
Run Code Online (Sandbox Code Playgroud)

结果为一个字符串

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
Run Code Online (Sandbox Code Playgroud)

注意

即使两个结果看起来相同(即打印它们时看起来相同),它们实际上是非常不同的,并允许不同的功能.

也就是说,使用list选项(第一个)允许您在orignal上执行功能id.

后者将允许您更容易地显示信息(包括导出到CSVexcel),但是要对id它们进行操作将需要将它们拼接回来.

  • 谢谢!我使用了 `paste(id, sep = ",")` 并最终得到了未聚合的结果。事实证明,我需要使用`paste(id,collapse = ",")`来代替。 (2认同)

Sam*_*rke 23

或者使用dplyr:

library(dplyr)
DF %>%
  group_by(brand) %>%
  summarise(id = paste(id, collapse = ","))
Run Code Online (Sandbox Code Playgroud)

哪里DF是你的data.frame的名称.

  • 不,就像在其他答案中一样,结果是一个 data.frame,带有一个名为 `id` 的向量,属于类 `character`,其中包含 `id` 的字符串,按问题中的要求用逗号分隔。`is.vector(DF$id)` 返回 `TRUE`。如果您对此方法有疑问,请考虑将其作为新问题发布。 (2认同)
  • 尝试添加“unique”,使其成为“paste(unique(id),collapse = ",")”——如果这不起作用,则值得发布一个新问题。 (2认同)

Fra*_*ank 10

这是基础R中的信息:

myby <- by(df$id,df$brand,function(x)paste(x,collapse=","))
Run Code Online (Sandbox Code Playgroud)

"by"对象的格式很奇怪.你可以采取data.frame(id=c(myby)),品牌将成为rownames:

#                                    id
# RadioShack                       2308
# Rag & Bone                       4466
# Ragu                        1830,4518
# Ralph Lauren 1638,2719,2720,2721,2722
Run Code Online (Sandbox Code Playgroud)

或者,如果您加载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
Run Code Online (Sandbox Code Playgroud)