r - 如何有效地计算 data.table 的唯一(数字)列向量?

标签 r data.table

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 个。

一般情况下请假设:

  1. foo 始终是数据表而不是矩阵;尽管列始终是数字。
  2. 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/

相关文章:

r - 非连续类别因子的欧几里得距离按组迭代

r - 有效地转换data.table中的日期列

r - 每天在 R 数据帧上应用 cut()

r - 如何从 R 中的数据框创建直方图

r - 从某个范围内的列表中计算值的简单函数

引用 R 中的前一行应用

R data.table : accessing column with variable name

r - Knitr HTML Loop - 一些 HTML 输出,一些 R 输出

r - 你如何改变 Sys.time() 的时区

r - 使用 Fread 读取带有双引号和逗号的字段时出错