foo <- data.table(x = 1:5/sum(1:5),
y = (-4):0/sum((-4):0),
z1 = 2:6/sum(2:6),
z2 = 2:6/sum(2:6))
假设我有 foo
数据表(如上所述):
x y z1 z2
1: 0.06666667 0.4 0.10 0.10
2: 0.13333333 0.3 0.15 0.15
3: 0.20000000 0.2 0.20 0.20
4: 0.26666667 0.1 0.25 0.25
5: 0.33333333 0.0 0.30 0.30
如何有效地计算唯一列?在这种情况下只有 3 个。
一般情况下请假设:
foo
始终是数据表而不是矩阵;尽管列始终是数字。foo
实际上很大,nrow > 20k 和 ncol > 100
是否可以在不制作额外数据副本的情况下执行此操作?
我目前的方法是使用 paste
在列上应用
,为每列获取一个值,然后执行 length(unique(.))
在结果上...
data.table::transpose()
、data.table::uniqueN
和其他 friend 有什么神奇之处吗?
最佳答案
另一种可能性:
length(unique(as.list(foo)))
这给出了预期的结果:
> length(unique(as.list(foo))) [1] 3
注意:length(unique())
的使用是必要的,因为 uniqueN()
将返回错误。
根据@Ryan 的评论,您还可以:
length(unique.default(foo))
关于速度,两种方法具有可比性(在 500 万行的较大数据集上测量时):
> fooLarge <- foo[rep(1:nrow(foo),1e6)] > microbenchmark(length(unique.default(fooLarge)), length(unique(as.list(fooLarge)))) Unit: milliseconds expr min lq mean median uq max neval cld length(unique.default(fooLarge)) 94.0433 94.56920 95.24076 95.01492 95.67131 103.15433 100 a length(unique(as.list(fooLarge))) 94.0254 94.68187 95.17648 95.02672 95.49857 99.19411 100 a
如果你只想保留唯一的列,你可以使用:
# option 1
cols <- !duplicated(as.list(foo))
foo[, ..cols]
# option 2 (doesn't retain the column names)
as.data.table(unique.default(foo))
给出(显示的输出选项 1):
x y z1 1: 0.06666667 0.4 0.10 2: 0.13333333 0.3 0.15 3: 0.20000000 0.2 0.20 4: 0.26666667 0.1 0.25 5: 0.33333333 0.0 0.30
关于r - 如何有效地计算 data.table 的唯一(数字)列向量?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50799031/