2016-07-26 4 views
1

그룹별로 내 데이터 집합의 충돌 수를 계산하고 싶습니다. data.table에서이 작업을 수행하는 쉬운 방법이 있어야 할 것처럼 느껴지지만 알아낼 수는 없습니다.R 데이터 테이블의 조건부 고유 카운팅

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의 고유 번호를 계산해야하는 다음 data.table의 각 행에 대해 충돌이있을 경우 내가 말해 더미 변수를 만들었습니다 그 수를 새로운 이름 열의 각 그룹에 적용하십시오. 이 대답이 있어야 할 것입니다 : 나는 sum(!is.na(unique(ID)))의 일부 사용에 대한 생각을 해 봤는데

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 

,하지만 난 조건부 데이터의 전 섹션에서 기준을 만들지 않고 고유 한 값을 계산하는 방법을 모르겠어요. 테이블 (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 (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