我有一个非常大的数据集(140000个obs * 125个属性)。每个ob与ID(可以是唯一的或不唯一的)相关联。我想为每个ID的每个属性(列)计算唯一值。
我试过了aggregate(. ~ ID, mydata, function(x) length(unique(x))
。但它不起作用。另外考虑到数据框的大小,我觉得即使它工作也可能需要很长时间才能完成。谁知道更好的方法呢?
数据集:
ID Attr1 Attr2 Attr3 Attr125
1 A X Y 123
1 B Z Y 345
1 B X Y 134
2 A Z Y abc
2 C Y Y def
3 D Y N xyz
4 B Z Y 789
我想要的结果:
ID Attr1 Attr2 Attr3 Attr125
1 2 2 1 3
2 2 2 1 2
3 1 1 1 1
4 1 1 1 1
答案 0 :(得分:3)
我这样做:
dat <- read.table("clipboard", header = T)
library(reshape2)
mdat <- melt(dat, id = "ID")
library(dplyr)
counts <- mdat %>% group_by(ID, variable) %>% summarize(n_unique = length(unique(value)))
> counts
ID variable n_unique
1 1 Attr1 2
2 1 Attr2 2
3 1 Attr3 1
4 1 Attr125 3
5 2 Attr1 2
6 2 Attr2 2
7 2 Attr3 1
8 2 Attr125 2
9 3 Attr1 1
10 3 Attr2 1
11 3 Attr3 1
12 3 Attr125 1
13 4 Attr1 1
14 4 Attr2 1
15 4 Attr3 1
16 4 Attr125 1
或者,再次重塑
> dcast(counts, ID ~ variable)
Using n_unique as value column: use value.var to override.
ID Attr1 Attr2 Attr3 Attr125
1 1 2 2 1 3
2 2 2 2 1 2
3 3 1 1 1 1
4 4 1 1 1 1
另一种可能首先不需要dplyr
的{{1}}解决方案:
melt
答案 1 :(得分:2)
我犹豫是否因为它与@ mgriebe的答案类似,但这是使用data.table
的另一种方式。我发现data.table
对这些操作很有用(但是,aggregate
调用对我来说效果很好):
# Load the data.table package
require( data.table )
# First copy your data.frame to a data.table
dt <- data.table( mydata )
# Count length of ID unique ID values for each column using the .SD operator of data.table
dt[ , lapply( .SD , function(x) length(unique(x)) ) , by=ID , .SDcols=2:5 ]`
# ID Attr1 Attr2 Attr3 Attr125
#1: 1 2 2 1 3
#2: 2 2 2 1 2
#3: 3 1 1 1 1
#4: 4 1 1 1 1
请务必将.SDcols
调整为存储属性的列号....