2014-11-19 2 views
1

이벤트 (1) 및 이벤트 (0)이없는 패널이 포함 된 데이터 프레임이 있습니다. 어떤 행에서 a와 b (예 : 2 및 3 등)가 모두 발생한 ID를 어떻게 식별 할 수 있습니까? ID 1과 5에서 a와 b는 두 열 중 하나에서 발생했으며 둘 다에서 발생하지 않았습니다.행 및 ID별로 이벤트 발생 확인

샘플 데이터와 나는 (열 발생) 몇 가지 방법은 다음

structure(list(id = c(1L, 1L, 2L, 2L, 3L, 3L, 3L, 4L, 4L, 5L, 
5L, 6L, 6L, 7L, 7L, 8L, 8L, 8L, 9L, 9L, 9L), a = c(0L, 0L, 1L, 
0L, 1L, 0L, 1L, 1L, 1L, 1L, 1L, 1L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 
1L, 0L), b = c(1L, 1L, 0L, 1L, 0L, 1L, 0L, 0L, 0L, 0L, 0L, 0L, 
1L, 1L, 1L, 1L, 1L, 1L, 1L, 0L, 1L), occur = c(0L, 0L, 1L, 1L, 
1L, 1L, 1L, 0L, 0L, 0L, 0L, 1L, 1L, 0L, 0L, 0L, 0L, 0L, 1L, 1L, 
1L)), .Names = c("id", "a", "b", "occur"), class = "data.frame", row.names = c(NA, 
-21L)) 
+0

그래서 당신이 결과는 같이 할 것으로 예상 않는 data.table 솔루션을입니까? 제발 게시물에 추가하십시오 –

+0

@ 리차드 나는 질문을 편집하고 가지고 싶은 것을 추가했습니다 – Meso

답변

3

여기

library(data.table) 
setDT(df)[, occur := as.numeric(sum(a) > 0 & sum(b) > 0), by = id][] 
# id a b occur 
# 1: 1 0 1  0 
# 2: 1 0 1  0 
# 3: 2 1 0  1 
# 4: 2 0 1  1 
# 5: 3 1 0  1 
# 6: 3 0 1  1 
# 7: 3 1 0  1 
# ... 
# ... 
3

아래에 표시되어 있고, 두 단지 고유 ID에 대해 다르게

tmp <- structure(list(id = c(1L, 1L, 2L, 2L, 3L, 3L, 3L, 4L, 4L, 5L, 
          5L, 6L, 6L, 7L, 7L, 8L, 8L, 8L, 9L, 9L, 9L), a = c(0L, 0L, 1L, 
                       0L, 1L, 0L, 1L, 1L, 1L, 1L, 1L, 1L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 
                       1L, 0L), b = c(1L, 1L, 0L, 1L, 0L, 1L, 0L, 0L, 0L, 0L, 0L, 0L, 
                           1L, 1L, 1L, 1L, 1L, 1L, 1L, 0L, 1L)), .Names = c("id", "a", "b" 
                           ), class = "data.frame", row.names = c(NA, -21L)) 

그룹화 같은 결과를 제공 할 것

cbind(unique(tmp$id), 
     c(by(tmp, tmp$id, FUN = function(x) all(colSums(x[, 2:3]) > 0)))) 

# [,1] [,2] 
# 1 1 0 
# 2 2 1 
# 3 3 1 
# 4 4 0 
# 5 5 0 
# 6 6 1 
# 7 7 0 
# 8 8 0 
# 9 9 1 

데이터의 열을 추가

,363,210
within(tmp, { 
    res <- ave(1:nrow(tmp), tmp$id, FUN = function(x) all(colSums(tmp[x, 2:3]) > 0)) 
}) 

# id a b res 
# 1 1 0 1 0 
# 2 1 0 1 0 
# 3 2 1 0 1 
# 4 2 0 1 1 
# 5 3 1 0 1 
# 6 3 0 1 1 
# 7 3 1 0 1 
# 8 4 1 0 0 
# 9 4 1 0 0 
# 10 5 1 0 0 
# 11 5 1 0 0 
# 12 6 1 0 1 
# 13 6 0 1 1 
# 14 7 0 1 0 
# 15 7 0 1 0 
# 16 8 0 1 0 
# 17 8 0 1 0 
# 18 8 0 1 0 
# 19 9 0 1 1 
# 20 9 1 0 1 
# 21 9 0 1 1 

대체 방법 :

library(plyr) 
ddply(tmp, .(id), summarise, res = sum(a) > 0 & sum(b) > 0) 
ddply(tmp, .(id), transform, res = sum(a) > 0 & sum(b) > 0) 

library(dplyr) 
group_by(tmp, id) %>% summarise(res = sum(a) > 0 & sum(b) > 0) 
group_by(tmp, id) %>% mutate(res = sum(a) > 0 & sum(b) > 0) 
2

집계 먼저 식별 아이디 :

aggr_mydf <- aggregate(mydf[,c('a','b')] , by=list(mydf$id), FUN='sum') 
colnames(aggr_mydf) <- c('id','a','b') #optional if you care about the names 
aggr_mydf$both <- apply(aggr_mydf,1,function(x) if(all(x)>0){1} else{0}) 

> aggr_mydf 
     id a b both 
1  1 0 2 0 
2  2 1 1 1 
3  3 2 1 1 
4  4 2 0 0 
5  5 2 0 0 
6  6 1 1 1 
7  7 0 2 0 
8  8 0 3 1 
9  9 1 2 1 

mydf <- merge(x = mydf, y = aggr_mydf, by = "id", all.x = TRUE) 
mydf <- mydf[c(-4,-5)] 
colnames(mydf) <- c('id','a','b','both') 

> mydf 
    id a b both 
1 1 0 1 0 
2 1 0 1 0 
3 2 1 0 1 
4 2 0 1 1 
5 3 1 0 1 
6 3 0 1 1 
7 3 1 0 1 
8 4 1 0 0 
9 4 1 0 0 
10 5 1 0 0 
11 5 1 0 0 
12 6 1 0 1 
13 6 0 1 1 
14 7 0 1 0 
15 7 0 1 0 
16 8 0 1 0 
17 8 0 1 0 
18 8 0 1 0 
19 9 0 1 1 
20 9 1 0 1 
21 9 0 1 1 
+0

당신은'a <- aggregate (. ~ id, df, sum); $ both <- rowSums (a [-1] == 0) == 0' –

+0

그래, 고마워. 그것은 참으로 좋아 보인다. – LyzandeR