2014-03-25 1 views
1

나는 한 달 전에 비슷한 질문을했다. 참조하십시오. Count the occurrences of unequal numbers from a data frame바깥 쪽 기능 및 벡터화 기능을 사용자 정의하는 방법은 무엇입니까?

outerVectorize 함수를 사용하여이 문제를 해결했습니다. 이것은 완벽하게 작동하지만 지금은 내 메모리 크기를 초과하는 거대한 행렬이

dist_mat<- outer(1:nrow(df),1:nrow(df), 
       FUN = Vectorize(function(i,j) sum(df[i,]!=df[j,]))) 

다음과 같이 내 솔루션입니다.

dist_mat을 얻은 후에는 각 행에 대해 2보다 작거나 같은 열 수를 계산합니다. 이제는 할 수 없습니다. 그래서, 메모리 문제를 피하기 위해 외부 함수에서 카운트 연산을 결합 할 수 있는지 궁금합니다. 내 결과는 벡터 일뿐입니다.

미리 감사드립니다. (가) 이동 얻을에서

tot.rows <- nrow(df) 
res <- numeric(tot.rows) 
for(i in 1:tot.rows) 
    for(j in 1:tot.rows) 
    res[[i]] <- res[[i]] + (sum(df[i,] != df[j,]) <= 2) 

outer 당신이 갈거야, 그래서 i * j 매트릭스를 사전 할당합니다 :이 엄격하게 귀하의 질문에 대답하지 않지만

+0

다른 질문에서 Roland의 대답에도 메모리 문제가 있습니까? [더 이상의 생각에 대해 내 의견을 편집하십시오 : 아마도 절반 이하로 작게 줄지 만 두 열을 더 추가하기 때문에 가능할 것입니다.] 이것은 메모리 문제를 해결하는 한 가지 방법 일 것입니다. 그렇다면 벡터화 된 연산을 사용하여 원하는 수를 얻을 수 있습니다. – Aaron

답변

1

, 당신은 아마 outer을 피하고 같은 것을 사용한다 바깥 쪽을 사용하면서 문제를 고치기가 힘듭니다. 결과가 실제로 데이터 프레임과 동일한 길이의 벡터 인 경우 응용 프로그램에서 nrow(df) * nrow(df) 차원의 행렬을 생성하는 outer이 필요하지 않습니다.

위의 알고리즘은 outer과 같은 계산 수를 실행하지만 신경 쓰는 것이 최종 계산이므로 메모리에 맞아야하므로 각 행마다 동일한 메모리 공간을 다시 사용합니다. 또한 외부의과 비슷한 속도 여야합니다 (테스트 한 장난감 예입니다). 벡터화 된 연산은 실제로 모든 값을 계산할 필요가 있고, outer과 같은 전체 확장을 처리 할 메모리가 있어야하지만 모든 것에 대한 해답이 될 필요는 없습니다.

이전 답변에서 지적했듯이 거리 계산이 대칭이므로 행렬의 대각선 또는 삼각형 중 하나를 계산하지 않도록 코드를 수정할 수 있으므로 계산 시간이 대략 절반에 달합니다. 당신은 매트릭스 DF를 가지고있는 경우에

+0

나는 vectorize를 가기 전에 이것을 시도했다.나는 기억 문제가 없지만 몇 시간 동안 실행됩니다. 아마 며칠 동안 (나는 6 시간 정도 후에 멈췄다). – Chris

+0

@Chris의 '외부 버전'은 느리게 실행되어야합니다. 메모리에 맞게 충분히 작은 데이터 하위 집합에 대한 두 가지 접근 방식의 성능을 비교 했습니까? 또한, 당신은 정말로 계산을 엄격하게 필요로하는 것으로 제한하려고합니다. 데이터에 중복 된 항목이 있습니까? 데이터 (숫자, 요소, 문자)는 무엇입니까? – BrodieG

+0

맞습니다, 바깥 쪽도 천천히. 나는 인자 데이터 타입을 가지고있다. 나는 이제 데이터를 줄이는 방법을 찾고있다. – Chris

1

다음

apply(DF, 2, function(y) sum(colSums(DF==y) < 2)) 

는 작동 할 수 있습니다? DF==yapply에서 각 열을 대상 열과 비교하면 colSums은 해당 열 쌍의 행 수가 동일한 지 알아 내고 그 값을 2와 비교합니다 (대상 열은 항상 DF = = y, 그래서 나는 그것을 고려했다 - 당신은 '2'문턱 값이 자기 - 자기 비교를 포함했는지 여부에 따라 그 주위를 놀아야 할 수도있다). 그리고 마지막으로 sum은 < 2 임계 값을 만족하는 열의 수를 계산합니다.

중간 거리 매트릭스가 필요 없다는 가정하에 코드가 완전히 다시 작성되었습니다.

+0

데이터를 효율적으로 만들 수있는 기능이있을 수도 있습니다. 예 : 'apply (DF, 1, anyDuplicated) == 0 '을 사용하여 중복 값이없는 행을 제거 할 수 있습니다. df의 차원은 무엇입니까? 열 조합이 많이 있습니까? 아니면 열의 길이입니까? –

+0

개빈, 나는 OP가 열이 아닌 행을 비교하려고 노력하고 있다고 생각합니다. 그리고 당신이 여기 반대편을하고있는 것처럼 보입니다 (제 생각에는?)? – BrodieG

+0

A'DF <- t (DF)'는 그것을 한 단계에서 열로 해석하고 다른 단계에서 행으로 해석하지 않는 한 그것을 정렬해야합니다, 이것은 전적으로 가능합니다! 그리고 그것이 OPs 데이터에서 가장 잘 작동하는 벤치마킹의 가치가 있습니다. 길거나 가늘거나 짧거나 넓거나 복제본의 유행 등을 알지 못하기 때문에 가치가 있습니다. –

관련 문제