题 如何按组向R data.frame添加唯一值的计数


我希望通过对第二个变量进行分组来计算唯一值的数量,然后将计数添加到现有data.frame作为新列。例如,如果现有数据框如下所示:

  color  type
1 black chair
2 black chair
3 black  sofa
4 green  sofa
5 green  sofa
6   red  sofa
7   red plate
8  blue  sofa
9  blue plate
10 blue chair

我想为每个人添加 color,独特的数量 types 存在于数据中:

  color  type unique_types
1 black chair            2
2 black chair            2
3 black  sofa            2
4 green  sofa            1
5 green  sofa            1
6   red  sofa            2
7   red plate            2
8  blue  sofa            3
9  blue plate            3
10 blue chair            3

我希望能用到 ave,但似乎找不到一个不需要很多行的简单方法。我有> 100,000行,所以我也不确定效率有多重要。

它有点类似于这个问题: 计算每组观察/行数并将结果添加到数据框


37
2017-07-02 09:18


起源




答案:


运用 ave (因为你具​​体要求):

within(df, { count <- ave(type, color, FUN=function(x) length(unique(x)))})

确保这一点 type 是字符向量而不是因素。


既然你也说你的数据很大,速度/性能可能是一个因素,我建议你 data.table 解决方案。

require(data.table)
setDT(df)[, count := uniqueN(type), by = color] # v1.9.6+
# if you don't want df to be modified by reference
ans = as.data.table(df)[, count := uniqueN(type), by = color]

uniqueN 实施于 v1.9.6 并且是一个更快的等价物 length(unique(.))。此外,它还适用于data.frames / data.tables。


其他方案:

使用plyr:

require(plyr)
ddply(df, .(color), mutate, count = length(unique(type)))

运用 aggregate

agg <- aggregate(data=df, type ~ color, function(x) length(unique(x)))
merge(df, agg, by="color", all=TRUE)

42
2017-07-02 09:24





这是一个解决方案 dplyr 包 - 它有 n_distinct() 作为包装 length(unique())

df %>%
  group_by(color) %>%
  mutate(unique_types = n_distinct(type))

36
2018-04-27 12:50





这也可以通过组合而在没有通过组操作的矢量化中实现 unique 同 table 要么 tabulate

如果 df$color 是 factor, 然后

table(unique(df)$color)[as.character(df$color)]
# black black black green green   red   red  blue  blue  blue 
#    2     2     2     1     1     2     2     3     3     3 

要么

tabulate(unique(df)$color)[as.integer(df$color)]
# [1] 2 2 2 1 1 2 2 3 3 3

如果 df$color 是 character 然后就是

table(unique(df)$color)[df$color]

如果 df$color 是一个 integer 然后就是

tabulate(unique(df)$color)[df$color]

5
2018-03-24 11:27