2012-03-28 4 views
0

여러 개의 주제에서 각각 여러 번 테스트 한 데이터가있는 R 데이터 프레임이 있습니다. 집합에 대한 통계를 수행하기 위해 subject ("id")에 대한 요인과 각 관찰 (factor "session"에 의해 주어진)에 대한 행이 있습니다. 나는.R : 적은 수의 행에 누락 된 값을 기반으로 여러 행을 제거하십시오.

위의 예에서
print(allData) 
id  session  measure 
1  1   7.6 
2  1   4.5 
3  1   5.5 
1  2   7.1 
2  2   NA 
3  2   4.9 

, 한 id == 2 행을 모두 제거 할 수있는 간단한 방법은 "측정 값"열은 1 행 NA를 포함 주어진있는 곳에 아이디 == 2?

각 주제에 대해 실제로 많은 측정 값 (열)과 4 개의 세션 (행)을 가지고 있기 때문에 주어진 수준의 "id"요소가있는 모든 행을 제거하는 우아한 방법이 있습니다. (적어도)이 "id"수준의 행 중 하나에 열에 NA가 포함되어 있습니까? 귀하의 예제 마지막 두를 사용 /조나스

+0

아마도 'sqldf'로 처리 할 수있는 방법이 있지만 근본적으로 더 간단하다고 생각하지 않습니다. –

답변

3

당신은 서브 data.frame 당신의 선택의 열의 NA가 포함되어있는 경우 2) NULL을 반환하는 함수를 적용, id하여 데이터를 부분 집합) 1로 plyr 패키지에서 ddply 기능을 사용할 수 있습니다 그렇지 않으면 data.frame 자체를 3) 모든 것을 다시 data.frame으로 연결합니다.

allData <- data.frame(id  = rep(1:4, 3), 
         session = rep(1:3, each = 4), 
         measure1 = sample(c(NA, 1:11)), 
         measure2 = sample(c(NA, 1:11)), 
         measure3 = sample(c(NA, 1:11)), 
         measure4 = sample(c(NA, 1:11))) 
allData      
# id session measure1 measure2 measure3 measure4 
# 1 1  1  3  7  10  6 
# 2 2  1  4  4  9  9 
# 3 3  1  6  6  7  10 
# 4 4  1  1  5  2  3 
# 5 1  2  NA  NA  5  11 
# 6 2  2  7  10  6  5 
# 7 3  2  9  8  4  2 
# 8 4  2  2  9  1  7 
# 9 1  3  5  1  3  8 
# 10 2  3  8  3  8  1 
# 11 3  3  11  11  11  4 
# 12 4  3  10  2  NA  NA 

# Which columns to check for NA's in 
probeColumns = c('measure1','measure4') 

library(plyr) 
ddply(allData, "id", 
     function(df)if(any(is.na(df[, probeColumns]))) NULL else df) 
# id session measure1 measure2 measure3 measure4 
# 1 2  1  4  4  9  9 
# 2 2  2  7  10  6  5 
# 3 2  3  8  3  8  1 
# 4 3  1  6  6  7  10 
# 5 3  2  9  8  4  2 
# 6 3  3  11  11  11  4 
+0

감사합니다, flodel! ddply 솔루션의 진정한 가치는 위의 집에서 만든 솔루션보다 훨씬 유연하다는 것입니다. 필요한 경우 조건과 연산을 함수에 추가 할 수 있습니다. –

0

# Which columns to check for NA's in 
probeColumns = c('measure1','measure4') # Etc... 

# A vector which contains all levels of "id" that are present in rows with NA's in the probeColumns 
idsWithNAs = allData[complete.cases(allData[probeColumns])==FALSE,"id"] 

# All rows that isn't in idsWithNAs 
cleanedData = allData[!allData$id %in% idsWithNAs,] 

감사 :

나는 나의 현재 솔루션보다 더 우아하게이 문제를 해결할 수있는 빌드 함수가있을 수 있다는 직관을 가지고 그러한 명령은 그러한 문자열로 변환 될 수 있습니다. 동일한 결과를 가져와야하며 더 단순 해 보입니다.

cleanedData <- allData[complete.cases(allData[,probeColumns]),] 

기본 패키지 만 사용하는 올바른 버전입니다. 재미로. :) 그러나 그것은 작고 간단하지 않습니다. flodel의 답변은 깔끔합니다. 귀하의 초기 솔루션조차도 더 작고 빨리 생각합니다.

cleanedData <- do.call(rbind, sapply(unique(allData[,"id"]), function(x) {if(all(!is.na(allData[allData$id==x, probeColumn]))) allData[allData$id==x,]})) 
+0

감사합니다. 그러나 제안서에서는 NA가있는 행만 삭제합니다 (위의 예에서 행 5). 나는 행 5와 같은 "id"레벨을 가지고 있기 때문에 행 2를 추가로 제거하는 솔루션을 찾고 있습니다. –

+0

@Jonas, 미안 해요, 당신이 정확히 원하는 것을 이해하지 못했습니다. 기본 패키지를 사용하는 재미있는 또 다른 답변을 추가하겠습니다. 그러나 flodel의 대답은 더 작고 멋지다. – DrDom