2012-01-05 3 views
1

두 데이터 프레임 (foo, bar)에 저장된 변수 집합 (X)을 비교하려고합니다. 각 X은 최대 10 개의 값이 Y과 연결된 고유 한 독립 변수입니다. 나는 모든 bar.X에 모든 foo.X를 비교하고 그들이 공통으로 가지고있는 Y 값의 수를 비교함으로써 - 출력은 foo.x 축이 bar.x 길이 인 행렬이 될 수있다.두 데이터 프레임에서 점수 매트릭스 만들기

foo는 바의 간단한 예는 2 × 2 행렬 C와 B, A 비교 반환 할 것, D :


가 편집

foo <- data.frame(x= c('a', 'a', 'a', 'b', 'b', 'b'), y=c('ab', 'ac', 'ad', 'ae', 'fx', 'fy')) 
bar <- data.frame(x= c('c', 'c', 'c', 'd', 'd', 'd'), y=c('ab', 'xy', 'xz', 'xy', 'fx', 'xz')) 
을 :


내가 떠 났어요 다른 초보자를위한 다음 코드는 배우기 쉽다 (for 루프는 효과적이지만 아마도 매우 차선책이다). 그러나 아래의 두 가지 해결책이 효과적이다. 특히 Ramnath의 data.table 사용은 매우 큰 데이터 프레임을 다룰 때 매우 효과적입니다.

저장소 (Y)의 값이 stack 함수

foo.list <- dlply(foo, .(x), function(x) stack(x, select = y)) 
bar.list <- dlply(bar, .(x),function(x) stack(x, select = y)) 

를 사용하여 저장된리스트와 dataframes는

comparelists <- function(list1, list2) { 
    for (i in list1){ 
    for (j in list2){ 
     count <- 0 
     if (i[[1]] %in% j[[1]]) count <- count + 1 
    } 
    } 
    return count 
    } 

는 출력 매트릭스를 작성 개의 적층리스트에 멤버를 비교하는 기능을 작성

output.matrix <- matrix(1:length(foo.list), 1:length(bar.list)) 
for (i in foo.list){ 
    for (j in bar.list){ 
    output.matrix[i,j] <- comparelists(i,j) 

    } 

답변

3

merge

library(reshape2) 
df1 <- merge(foo, bar, by = 'y') 
dcast(df1, x.x ~ x.y, length) 

    x.x c d 
1 a 1 0 
2 b 0 1 

편집을 사용하여 간단한 방법입니다 : 나를 여기에 비교적 간단 느낌 하나입니다. 병합은 data.table을 사용하면 더 빨라질 수 있습니다. 코드는 다음과 같습니다

foo_dt <- data.table(foo, key = 'y') 
bar_dt <- data.table(bar, key = 'y') 
df1 <- bar_dt[foo_dt, nomatch = 0] 
+0

@ ramnath에게 감사드립니다. 이것은 실제로 매우 우아하고 쉬운 해결책입니다. 불행히도이 사람은 전체 데이터 세트에 적용 할 때 내 컴퓨터를 손상시킵니다. 나는 내 데이터를 처리하기 위해 파이썬을 사용하는 나의 사전 R 전략으로 돌아갈 것이라고 생각한다. (나는 데이터를 반복하고 파일에 결과를 써서 컴퓨터가 뒤집히지 않도록한다.) 그리고 그래프를 위해 R을 사용한다. capabilites. – zach

+0

'foo'와'bar'의 크기는 얼마나됩니까? – Ramnath

+0

내 편집을 확인하십시오. 그것은'merge'를하기 위해'data.table'을 사용하므로 매우 효율적입니다. 이게 효과가 있는지 확인할 수 있습니까? 그 단계가 병목이면 데이터를 '캐스팅'하는 효율적인 방법을 찾으려고합니다. – Ramnath

4

이렇게하는 방법은 100 가지가되어야합니다. 여기

library(reshape2) 
foo <- data.frame(x = c('a', 'a', 'a', 'b', 'b', 'b'), 
        y = c('ab', 'ac', 'ad', 'ae', 'fx', 'fy')) 
bar <- data.frame(x = c('c', 'c', 'c', 'd', 'd', 'd'), 
        y = c('ab', 'xy', 'xz', 'xy', 'fx', 'xz')) 

# Create a function that counts the number of common elements in two groups 
nShared <- function(A, B) { 
    length(intersect(with(foo, y[x==A]), with(bar, y[x==B]))) 
} 

# Enumerate all combinations of groups in foo and bar 
(combos <- expand.grid(foo.x=unique(foo$x), bar.x=unique(bar$x))) 
# foo.x bar.x 
# 1  a  c 
# 2  b  c 
# 3  a  d 
# 4  b  d 

# Find number of elements in common among all pairs of groups 
combos$n <- mapply(nShared, A=combos$foo.x, B=combos$bar.x) 

# Reshape results into matrix form 
dcast(combos, foo.x ~ bar.x) 
# foo.x c d 
# 1  a 1 0 
# 2  b 0 1 
+0

nice! 큰 격자로 확장하고 중복을 계산 한 다음 다시 작성하는 것을 봅니다. 우아한. 그러나 foo와 bar가 실제로 수천 명의 회원이되면 어떨까요? 방법을 바꿀까요? – zach

+0

계산이 정말로 느려지지 않으면 변경하지 않겠습니다. 그러나 이것은 더 큰 데이터 세트에 대해 꽤 잘 확장되어야한다고 생각합니다. –

+0

Josh. 나는 R에서 충분히 교차하지 않았고, expand.grid, dcast 또는 mapply를 사용하지 않았다. 그래서 빠른 답변을 얻는 것 외에도 이것은 진정한 도움이된다! – zach

관련 문제