2013-01-23 4 views
3

다른 행 수와 같은 수의 데이터 프레임이 있습니다. 아래의 예에서 데이터 프레임 1은 4 x 2이고 데이터 프레임 2는 3 x 2입니다. 4 x 3 논리 행렬이 필요합니다. 여기서 TRUE는 데이터 프레임의 모든 행이 일치 함을 나타냅니다. 이 예제는 작동하지만 더 큰 데이터 프레임으로 실행하는 데 오랜 시간이 걸립니다 (약 5,000 개의 행을 가진 두 개의 데이터 프레임을 시도하지만 여전히 두 개의 열만 있음). 이 작업을 수행하는보다 효율적인 방법이 있습니까?두 데이터 프레임을 비교하는 효과적인 방법이 있습니까

> df1 <- data.frame(row.names=1:4, var1=c(TRUE, TRUE, FALSE, FALSE), var2=c(1,2,3,4)) 
> df2 <- data.frame(row.names=5:7, var1=c(FALSE, TRUE, FALSE), var2=c(5,2,3)) 
> 
> m1 <- t(as.matrix(df1)) 
> m2 <- as.matrix(df2) 
> 
> apply(m2, 1, FUN=function(x) { apply(m1, 2, FUN=function(y) { all(x==y) }) }) 
     5  6  7 
1 FALSE FALSE FALSE 
2 FALSE TRUE FALSE 
3 FALSE FALSE TRUE 
4 FALSE FALSE FALSE 

미리 도움을 청하십시오. 이 빨라집니다 경우

답변

0

는 솔직히 잘 모르겠어요,하지만 당신은 시도 할 수 있습니다 :

foo <- Vectorize(function(x,y) {all(df1[x,] == df2[y,])}) 
> outer(1:4,1:3,FUN = foo) 
     [,1] [,2] [,3] 
[1,] FALSE FALSE FALSE 
[2,] FALSE TRUE FALSE 
[3,] FALSE FALSE TRUE 
[4,] FALSE FALSE FALSE 

나는 적어도 all.equal 또는 identical에 반대 비교를 == 사용에 위험을 언급 가고픈 충동이 들게. 당신이 데이터 타입을 충분히 편안하게 사용할 수 있다고 생각합니다. 문제가되지 않을 것입니다.

1

내가 R-블로거에 우편으로 여기에 그려진 : 당신이 말하는 것처럼, 데이터가없는 숫자 벡터가없는 경우 http://jason.bryer.org/posts/2013-01-24/Comparing_Two_Data_Frames.html

, 나는 내가 빠른 접근 방식을 제안 할 수 있습니다 생각합니다. 그것은으로 구성되어

  1. 당신이 datas의 행 사이의 유클리드 거리를 계산 정수의 두 행렬로 두 data.frames을 설정

빠른 예를 들어 데이터 사용 :

mat1 <- as.matrix(sapply(df1, as.integer)) 
mat2 <- as.matrix(sapply(df2, as.integer)) 
library(fields) 
rdist(mat1, mat2) < 1e-9 
#  [,1] [,2] [,3] 
# [1,] FALSE FALSE FALSE 
# [2,] FALSE TRUE FALSE 
# [3,] FALSE FALSE TRUE 
# [4,] FALSE FALSE FALSE 

몇 가지 의견 :

  1. 데이터에 문자의 벡터가 포함되어있는 경우 요인으로 변환하고 동일한 요소 수준을 공유해야합니다.
  2. 유클리드 거리를 계산할 때 fields 패키지를 사용했습니다. Fortran 구현을 사용하고 있으며 가장 빠른 R 패키지를 알고 있습니다. 많은 테스트를 거쳐 저를 신뢰합니다.
0

나는 최적의 솔루션은 얼마나 많은 고유 한 행과 당신이 가진 총 행 수. 각

  1. 할당 ID를 : 1,000에서 1,500 사이 행 만 20 고유 값이있는 블로그,에 예를 들어

    은 (당신이 설정 한 종자), 나는이 일을 빨리 생각 고유 한 행을 찾은 다음
  2. 각 data.frame에 표시된 ID의 벡터에서 외부를 실행합니다.

여기 성능이 있습니다. @ flodel의 접근 방식은 내 컴퓨터에서 거의 동일합니다. 그것은 아래 세 번째 것입니다. 면책 조항 : 나는 이런 종류의 테스트를 실행하는 것에 대해 많이 알지 못합니다.

> set.seed(2112) 
> df1 <- data.frame(row.names=1:1000, 
+ var1=sample(c(TRUE,FALSE), 1000, replace=TRUE), 
+ var2=sample(1:10, 1000, replace=TRUE)) 
> df2 <- data.frame(row.names=1001:2500, 
+ var1=sample(c(TRUE,FALSE), 1500, replace=TRUE), 
+ var2=sample(1:10, 1500, replace=TRUE)) 
> 
> # candidate method on blog 
> system.time({ 
+ df1$var3 <- apply(df1, 1, paste, collapse='.') 
+ df2$var3 <- apply(df2, 1, paste, collapse='.') 
+ df6 <- sapply(df2$var3, FUN=function(x) { x == df1$var3 }) 
+ dimnames(df6) <- list(row.names(df1), row.names(df2)) 
+ }) 
    user system elapsed 
    1.13 0.00 1.14 
> 
> rownames(df1) <- NULL # in case something weird happens to rownames on merge 
> rownames(df2) <- NULL 
> # id method 
> system.time({ 
+ df12 <- unique(rbind(df1,df2)) 
+ df12$id <- rownames(df12) 
+ 
+ id1 <- merge(df12,df1)$id 
+ id2 <- merge(df12,df2)$id 
+ 
+ x <- outer(id1,id2,`==`) 
+ }) 
    user system elapsed 
    0.11 0.02 0.13 
> 
> library(fields) 
> # rdlist from fields method 
> system.time({ 
+ mat1 <- as.matrix(sapply(df1, as.integer)) 
+ mat2 <- as.matrix(sapply(df2, as.integer)) 
+ rdist(mat1, mat2) < 1e-9 
+ }) 
    user system elapsed 
    0.15 0.00 0.16 

은 내가 rbind 추측과 merge의 다른 데이터와이 솔루션은 상대적으로 비용이 많이 드는 만들 것입니다.

+0

저는 R 블로거에 대한 귀하의 게시물을 보았던 @ flodel 님이보기에이 점을 보았습니다. 연쇄 반응. – Frank

관련 문제