【问题标题】:Fastest way/algorithm to find count of unique rows of a sorted file查找已排序文件的唯一行数的最快方法/算法
【发布时间】:2013-07-22 14:50:42
【问题描述】:

我目前使用.N 来查找使用by= ... . 的文件中的唯一行数

例如。要在数据表 dt 中查找 col1col2 的唯一行数,查询将是,

dt[, .N, by="col1,col2"]

对于非常大的文件,这可能需要很长时间。如果表格已排序,是否有更快的方法来做到这一点?基本上,您可以设置一个计数器,并在每次遇到唯一行时使用单个条目将其更新为每行出现的次数。我不能使用 for 循环,因为那会花很长时间。

【问题讨论】:

  • 再一次,绝对没有理由添加“rcpp”标签。请编辑——当你在做的时候,也许可以在这里学习如何格式化代码。这一切都记录得很好......
  • 我感谢大家的编辑,但我仍然希望 OP 自己做出适当的努力。
  • 当然,明白。从 iPhone 发布,可能没有正确输入代码的空格。不管怎样,感谢您给我们 rcpp,经过很长时间,我终于可以声称并证明 R 足以处理所有那些 mgmt 曾经移交给已批准预算的主流语言开发人员的项目。
  • 我有点疑惑。使用 table 函数,我从来没有遇到过“非常长”的延迟。
  • 我还想看到一些证明问题中显示的 data.table 查询需要“很长时间”的证据。您如何在这里定义“非常长”?

标签: r data.table


【解决方案1】:

unique.data.table 与基本 R unique 非常不同,因为如果设置了键,unique.data.table 仅基于 data.table 的键列获取唯一值。用一个例子来解释这一点,

试试这个:

dt <- data.table(x=c(1,1,1,2,2), y=c(5,6,6,7,8))
unique(dt) # no key set, similar to 'unique.data.frame' output

# set key now
setkey(dt, "x")
unique(dt) # unique based on just column x

如果您只想获取唯一行的总数,请尝试以下操作:

setkeyv(dt, c("col1", "col2"))
nrow(unique(dt))

【讨论】:

  • 这似乎与按原样在桌子上运行唯一的时间相同.. ?有没有办法指定正在读取的表已经排序,例如,读取排序的 csv 文件 ...。基本上避免了运行 setkey。
  • 刚刚意识到如果x 已经排序,那么您可以设置:setattr(dt, 'sorted', 'x'),以便直接将键设置为x 而不是排序.. 和这可以节省相当多的时间!感谢 @eddi 提供的这个 hack (go here)。
【解决方案2】:

关于你的问题:

dt[, .N, by="col1,col2"]

实际上并没有给你唯一行的数量,而这两个中的任何一个都可以:

dt[, .N, by="col1,col2"][, .N] # data.table solution
nrow(dt[, .N, by="col1,col2"]) # data.frame syntax applied to data.table

我对你的问题的回答:

data.table 包的一个核心特性是使用密钥。在第 2 页从 short introduction 到 data.table 包它读取:

此外,行按键排序。因此,一个 data.table 最多可以有一个键,因为它不能被排序在一个以上 方式。

因此,除非您有一列定义了可以设置为键的排序顺序,否则您的数据已排序这一事实将毫无用处。因此,您需要设置密钥。出于您的目的(大型数据文件,因此假设有很多列),您可能希望包含数据集中的所有列以设置键:

setkeyv(dt,c(names(dt))) # use key(dt) to check whether this went as expected
unique(dt)[, .N] # or nrow(unique(dt))

PS:请向我们提供可复制的数据集,以便我们评估您认为的快慢。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-03-25
    • 1970-01-01
    • 2018-07-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-02-16
    相关资源
    最近更新 更多