Bry*_*yan 53 aggregate r unique count
我希望通过对第二个变量进行分组来计算唯一值的数量,然后将计数添加到现有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
Run Code Online (Sandbox Code Playgroud)
我想为每个添加数据中存在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
Run Code Online (Sandbox Code Playgroud)
我希望使用ave,但似乎无法找到一个不需要很多行的直接方法.我有> 100,000行,所以我也不确定效率有多重要.
它与此问题有些类似:计算每组观察/行数并将结果添加到数据框
Aru*_*run 60
使用ave(因为你具体要求):
within(df, { count <- ave(type, color, FUN=function(x) length(unique(x)))})
Run Code Online (Sandbox Code Playgroud)
确保它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]
Run Code Online (Sandbox Code Playgroud)
uniqueN是实现的v1.9.6,是一个更快的等价物length(unique(.)).此外,它还适用于data.frames/data.tables.
其他方案:
使用plyr:
require(plyr)
ddply(df, .(color), mutate, count = length(unique(type)))
Run Code Online (Sandbox Code Playgroud)
使用aggregate:
agg <- aggregate(data=df, type ~ color, function(x) length(unique(x)))
merge(df, agg, by="color", all=TRUE)
Run Code Online (Sandbox Code Playgroud)
Sam*_*rke 52
这是dplyr包的解决方案- 它有n_distinct()一个包装器length(unique()).
df %>%
group_by(color) %>%
mutate(unique_types = n_distinct(type))
Run Code Online (Sandbox Code Playgroud)
这也可以通过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
Run Code Online (Sandbox Code Playgroud)
要么
tabulate(unique(df)$color)[as.integer(df$color)]
# [1] 2 2 2 1 1 2 2 3 3 3
Run Code Online (Sandbox Code Playgroud)
如果df$color是character那么
table(unique(df)$color)[df$color]
Run Code Online (Sandbox Code Playgroud)
如果df$color是integer那么只是
tabulate(unique(df)$color)[df$color]
Run Code Online (Sandbox Code Playgroud)