2011-10-19 6 views
6

[업데이트 1 : Matthew Dowle이 지적했듯이 CR-N이 아닌 R-Forge에서 data.table 버전 1.6.7을 사용하고 있습니다. data.table의 이전 버전에서 동일한 동작을 볼 수 없습니다.]R의 데이터 프레임에서 데이터 테이블로의 설정 작업 포팅 : 중복 된 행을 식별하는 방법?

배경 : 데이터 프레임 또는 데이터 프레임 쌍의 행에 대해 집합 연산을 수행 할 수있는 약간의 유틸리티 함수를 이식합니다 (예 : 각 행은 세트의 요소), 예. (Matlab)의 intersect(...,'rows'), setdiff(...,'rows') 등을 모방 한 것으로 R (R의 집합 연산은 벡터와리스트로 제한됩니다)을 모방 한 것으로, 목록, 조합, 교차, 집합 차 등에서 집합을 만들 수 있습니다. 행렬이나 데이터 프레임의 행은 아닙니다). 이러한 작은 기능의 예는 다음과 같습니다. 데이터 프레임에 대한이 기능이 이미 일부 패키지 또는 기본 R에 존재하는 경우 제안에 대해 개방적입니다.

저는 이것을 데이터 테이블로 마이그레이션했으며 현재 접근법에서 필요한 단계는 중복 된 행을 찾는 것입니다. duplicated()이 실행되면 데이터 테이블에 키가 있어야한다는 오류가 반환됩니다. 이것은 보편적 인 솔루션이 아니며 계산 비용을 추가하는 키 설정 이외에도 중복 객체를 찾는 다른 방법이 있습니까?

library(data.table) 
set.seed(0) 
x <- as.data.table(matrix(sample(2, 100, replace = TRUE), ncol = 4)) 
y <- as.data.table(matrix(sample(2, 100, replace = TRUE), ncol = 4)) 

res3 <- dt_intersect(x,y) 

이 오류 메시지가 항복 : 데이터 프레임에 대해있는 그대로 내가 패턴 dt_operation 각 기능이라는 것하지만

Error in duplicated.data.table(z_rbind) : data table must have keys 

코드가 작동을 여기

는 재현 예입니다 .

이 문제를 해결할 수있는 방법이 있습니까? 설정 키는 정수에만 적용됩니다. 이는 입력 데이터에 대해 가정 할 수없는 제약 사항입니다. 그래서, 아마도 나는 데이터 테이블을 사용하는 영리한 방법을 놓치고 있습니까?

dt_unique  <- function(x){ 
    return(unique(x)) 
} 

dt_union  <- function(x,y){ 
    z_rbind  <- rbind(x,y) 
    z_unique <- dt_unique(z_rbind) 
    return(z_unique) 
} 

dt_intersect <- function(x,y){ 
    zx   <- dt_unique(x) 
    zy   <- dt_unique(y) 

    z_rbind  <- rbind(zy,zx) 
    ixDupe  <- which(duplicated(z_rbind)) 
    z   <- z_rbind[ixDupe,] 
    return(z) 
} 

dt_setdiff  <- function(x,y){ 
    zx   <- dt_unique(x) 
    zy   <- dt_unique(y) 

    z_rbind  <- rbind(zy,zx) 
    ixRangeX <- (nrow(zy) + 1):nrow(z_rbind) 
    ixNotDupe <- which(!duplicated(z_rbind)) 
    ixDiff  <- intersect(ixNotDupe, ixRangeX) 
    diffX  <- z_rbind[ixDiff,] 
    return(diffX) 
} 

주 1 : 세트의 요소는 데이터 행이다


예 설정된 운전 기능이 헬퍼 기능을위한 하나 개의 용도는 키 값 행을 찾을 곳이다 in x는 y의 키 값 중 하나가 아닙니다. 이렇게하면 x[y] 또는 y[x]을 계산할 때 NA가 나타나는 위치를 찾을 수 있습니다. 이 사용법은 z_rbind 객체의 키 설정을 허용하지만,이 유스 케이스만으로는 제한하지 않는 것이 좋습니다.

참고 2 : 관련 게시물의 경우 데이터 프레임에 unique을 실행하면 here is a post이 표시되고 업데이트 된 data.table 패키지로 실행하면 우수한 결과가 나타납니다. 그리고 데이터 테이블에 unique을 실행 중일 때는 this is an earlier post입니다.

답변

6

duplicated.data.table에는 수정본 unique.data.table이 필요합니다. [편집 : 이제 v1.7.2에서 완료되었습니다.] 다른 버그 보고서를 제기하십시오 : bug.report(package="data.table"). 다른 사람들이 시청할 수 있도록 이미 CR-1.6.6이 아닌 R-Forge의 v1.6.7을 사용하고 있습니다.

x[-x[y,which=TRUE]] 

FR#1384는 (? '하지'와 'whichna'인수가 새로운) 사용자가보다 쉽게 ​​참조 및 링크가 : 주 1에

그러나이하는 '가입하지'관용구있다 자세한 내용은 keys that don't match 스레드로 이동하십시오.


업데이트. 이제 v1.8.3에서 not-join이 구현되었습니다.

DT[-DT["a",which=TRUE,nomatch=0],...] # old idiom 
DT[!"a",...]       # same result, now preferred. 
+0

고마워요! 좋은 지적 - 나는'data.table'을 갱신했다는 것을 잊었다. 또한,'bug.report()'는 나에게 새롭다. – Iterator

+0

Matthew, 당신의 코드는'x [-x [y, which = TRUE, nomatch = 0]]'이어야합니까? 'nomatch = 0' 인자가 없으면 나는 다음 에러를 얻는다 :'[.default (x [[s]], irows)의 에러 : 오직 0은 음의 첨자와 혼합 될 수있다 .' – Ryogi

+0

@RYogi. 확실하지 않다. 새로운 질문에 예를 들어주세요. –