2016-07-26 85 views
1

我想按组来计算我的数据集中的冲突数。我觉得在data.table中必须有一个简单的方法来做到这一点,但似乎无法弄清楚。我创建了一个虚拟变量来告诉我,如果没有为data.table的每一行冲突:R 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)))一些用法,但我不知道如何有条件地算唯一值,而不在数据的I部分创造条件。表(Conflict == 1)

回答

4

您可以在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)] 
+0

为什么在'j'内条件?我想它会变慢。 'testDT [!is.na(ID)&Conflict == 1,Count:= uniqueN(ID),by =。(Name,Division)]'对整个表执行所有逻辑测试,而不是在每组。除非我失去了一些东西 – MichaelChirico

+1

哦,我明白了。这将为这些行分配“NA”。至于@shughes如果重要... – MichaelChirico

+1

哦,另一件事。 'uniqueN'有一个'na.rm'参数,所以你可以用它来代替is.na。不过,根据你所使用的版本,这可能会给你带来一个错误。 (我必须更新才能通过https://github.com/Rdatatable/data.table/issues/1771) – Frank

0

这里是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