61

我有一种需求,我认为可以通过aggregateor来满足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

我将如何做到这一点?

4

4 回答 4

73

让我们称您为 data.frameDF

> 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 在评论中提到的那样,另一种选择是使用该toString功能:

aggregate(id ~ brand, data = DF, toString)
于 2013-05-16T20:12:37.103 回答
42

一条很干净的线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

笔记

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

即,使用 list 选项(第一个)允许您在原始ids 上执行功能。

后者将允许您更轻松地显示信息(包括导出到CSVor excel),但要对id' 进行操作将需要将它们拼接回来。

于 2013-05-16T21:09:02.847 回答
31

或使用dplyr

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

DF您的 data.frame 的名称在哪里。

于 2015-05-22T12:39:31.577 回答
11

这是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
于 2013-05-16T20:17:49.493 回答