2016-07-26 2 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)) 

мне нужно подсчитать уникальный номер не-NA идентификаторов, которые имеют флаг конфликтную 1 и применять этот счет в новом столбце для каждой группировки 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))), но я не уверен, как условно считать уникальные значения без создания критериев в разделе я данные. таблица (Conflict == 1).

ответ

4

Вы можете подмножество в ID переменных условий в data.table [] и затем подсчитать уникальные значения:

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 
Смежные вопросы