【问题标题】:Conditional Unique Counting in R data.tableR data.table 中的条件唯一计数
【发布时间】:2016-07-26 01:11:01
【问题描述】:

我想按组计算我的数据集中的冲突数量。我觉得在 data.table 中必须有一种简单的方法来做到这一点,但似乎无法弄清楚。我创建了一个虚拟变量来告诉我 data.table 的每一行是否存在冲突:

testDT <- data.table(Name = c(rep('A',6),rep('B',5)),
                     Division = c(rep(11,6),rep(12,5)),
                     ID = c(205,205,NA,201,201,201,203,203,203,204,NA),
                     Conflict = c(0,0,0,1,1,1,1,1,1,1,0))

我需要计算冲突标志为 1 的非 NA ID 的唯一数量,并将新列中的计数应用于每个 Name-Division 分组。答案应该是这样的:

testDT[, Count := c(rep(1,6),rep(2,5))]

    Name Division  ID Conflict Count
 1:    A       11 205        0     1
 2:    A       11 205        0     1
 3:    A       11  NA        0     1
 4:    A       11 201        1     1
 5:    A       11 201        1     1
 6:    A       11 201        1     1
 7:    B       12 203        1     2
 8:    B       12 203        1     2
 9:    B       12 203        1     2
10:    B       12 204        1     2
11:    B       12  NA        0     2

我一直在考虑 sum(!is.na(unique(ID))) 的一些用法,但我不确定如何在 data.table (Conflict == 1) 的 i 部分不创建条件的情况下有条件地计算唯一值。

【问题讨论】:

    标签: r data.table


    【解决方案1】:

    您可以通过data.table [] 中的条件对ID 变量进行子集化,然后计算唯一值:

    library(data.table)
    testDT[, Count := uniqueN(ID[!is.na(ID) & Conflict == 1]), by=.(Name, Division)]
    testDT
    #     Name Division  ID Conflict Count
    #  1:    A       11 205        0     1
    #  2:    A       11 205        0     1
    #  3:    A       11  NA        0     1
    #  4:    A       11 201        1     1
    #  5:    A       11 201        1     1
    #  6:    A       11 201        1     1
    #  7:    B       12 203        1     2
    #  8:    B       12 203        1     2
    #  9:    B       12 203        1     2
    # 10:    B       12 204        1     2
    # 11:    B       12  NA        0     2
    

    或者按照你的逻辑:

    testDT[, Count := sum(!is.na(unique(ID[Conflict == 1]))), by=.(Name, Division)]
    

    【讨论】:

    • 为什么条件在j 内?我想它会更慢。 testDT[!is.na(ID) &amp; Conflict == 1, Count := uniqueN(ID), by = .(Name, Division)] 对整个表执行所有逻辑测试,而不是对每个组进行测试。除非我错过了什么
    • 哦,我明白了。这将为这些行分配NAs。如果这很重要,请联系@shughes...
    • 哦,还有一件事。 uniqueN 有一个 na.rm 参数,因此您可以使用它来代替!is.na 的条件。不过,根据您使用的版本,这可能会给您带来错误。 (我必须更新才能通过它github.com/Rdatatable/data.table/issues/1771
    【解决方案2】:

    这是dplyr的选项

    library(dplyr)
    testDT %>%
        group_by(Name, Division) %>% 
        mutate(Count = n_distinct(ID[!is.na(ID) & Conflict==1]))
    #    Name Division    ID Conflict Count
    #   <chr>    <dbl> <dbl>    <dbl> <int>
    #1      A       11   205        0     1
    #2      A       11   205        0     1
    #3      A       11    NA        0     1
    #4      A       11   201        1     1
    #5      A       11   201        1     1
    #6      A       11   201        1     1
    #7      B       12   203        1     2
    #8      B       12   203        1     2
    #9      B       12   203        1     2
    #10     B       12   204        1     2
    #11     B       12    NA        0     2
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2022-10-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-09-05
      相关资源
      最近更新 更多