【问题标题】:Extracting unique rows from a data table in R [duplicate]从R中的数据表中提取唯一行[重复]
【发布时间】:2011-11-25 14:40:56
【问题描述】:

我正在从数据框和矩阵迁移到数据表,但还没有找到从数据表中提取唯一行的解决方案。我想我在[,J] 表示法上遗漏了一些东西,尽管我还没有在常见问题解答和介绍小插曲中找到答案。如何在不转换回数据帧的情况下提取唯一行?

这是一个例子:

library(data.table)
set.seed(123)
a <- matrix(sample(2, 120, replace = TRUE), ncol = 3)
a <- as.data.frame(a)
b <- as.data.table(a)

# Confirm dimensionality
dim(a) # 40  3
dim(b) # 40  3

# Unique rows using all columns
dim(unique(a))  # 8 3
dim(unique(b))  # 34 3

# Unique rows using only a subset of columns
dim(unique(a[,c("V1","V2")]))   # 4 2
dim(unique(b[,list(V1,V2)]))    # 29 2

相关问题:这种行为是否是数据未排序的结果,就像 Unix uniq 函数一样?

【问题讨论】:

    标签: r data.table


    【解决方案1】:

    在 data.table v1.9.8 之前,unique.data.table 方法的默认行为是使用键来确定应该返回唯一组合的列。如果keyNULL(默认值),则可以取回原始数据集(如在 OP 情况下)。

    从 data.table 1.9.8+ 开始,unique.data.table 方法默认使用所有列,这与基础 R 中的 unique.data.frame 一致。要让它使用键列,请将 by = key(DT) 显式传递给 @987654329 @(将调用 key 中的 DT 替换为 data.table 的名称)。

    因此,旧的行为类似于

    library(data.table) v1.9.7-
    set.seed(123)
    a <- as.data.frame(matrix(sample(2, 120, replace = TRUE), ncol = 3))
    b <- data.table(a, key = names(a))
    ## key(b)
    ## [1] "V1" "V2" "V3"
    dim(unique(b)) 
    ## [1] 8 3
    

    而对于 data.table v1.9.8+,只是

    b <- data.table(a) 
    dim(unique(b)) 
    ## [1] 8 3
    ## or dim(unique(b, by = key(b)) # in case you have keys you want to use them
    

    或者没有副本

    setDT(a)
    dim(unique(a))
    ## [1] 8 3
    

    【讨论】:

    • 这很有趣。实际上,这种行为类似于 Unix 的 uniq 函数:它取决于被排序的数据。我没有检查基本 R 函数 unique 是否依赖于排序,尽管它似乎以原始顺序呈现输出。顺便说一句,您在文档中的哪里找到这个?我一定错过了那部分。
    • 查看data.table中duplicated()的条目pdf,或者试试?unique.data.table。
    • 优秀的指点!我看到unique 隐藏在文档中。希望这将得到解决。在?unique.data.table 上找到好东西。我也忽略了尝试methods(class = "data.table")
    • 我已经提出bug #1601 来解决原始问题。谢谢。
    • 这已在 v1.6.7 中得到修复,因此在未排序的数据上是独一无二的。现在无需设置键即可工作。还改进了文档。
    【解决方案2】:

    正如 Seth 所说,data.table 包已经发展,现在为此提出了优化的功能。

    对于所有不想进入文档的人,这里是做你想做的最快和最节省内存的方法:

    uniqueN(a)
    

    如果您只想选择列的子集,您可以使用 'by' 参数:

    uniqueN(a,by = c('V1','V2'))

    编辑:正如在 cmets 中提到的,这只会给出唯一行的计数。要获取唯一值,请改用 unique :

    unique(a)

    对于一个子集:

    unique(a[c('V1',"V2")], by=c('V1','V2'))

    【讨论】:

    • mm 当我这样做时,我没有得到一个 data.table,我只是得到一个带有观察次数的向量?也就是某种总结。
    • 这个问题不是关于计算唯一性,而是提取唯一行,所以我看不出你的答案如何回答这个问题。
    • @DavidArenburg 你是对的。如果您想获取行数而不是行数,我刚刚编辑了答案。
    • 这并没有为现有答案添加任何内容。这就是我最初的观点。如果您对现有答案进行了一些小的修改,您应该对其进行编辑而不是发布新的。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-03-30
    • 2017-02-21
    • 1970-01-01
    • 2018-10-13
    • 2016-11-03
    • 1970-01-01
    相关资源
    最近更新 更多