2014-09-09 3 views
0

데이터 프레임이 f이고 1.5kk 행부터 시작하여 f 데이터 프레임을 기준으로 nxn 데이터 프레임 Channels을 업데이트하려고합니다. 지금까지 매우 느린 스크립트 실행으로 이어지는 2 for-loops이 있습니다.1.5k 행에서 루핑하고 데이터 프레임을 업데이트하는 가장 효율적인 방법

id_user | id_channel 
-------------------- 
    1 |  43 
    1 |  61 
    1 | 101 
    2 |  43 
    2 | 631 
    .. |  .. 

내가 얻을 것으로 기대하는 것은으로 dataframe Channels입니다 :

은 내가 그들 대부분이 (당신은 그들이 가장 좋아하는 노래의 장르로 생각할 수있다) 같은 사용자 ID와 채널을 아래 표와 같이가 I는 x 및 y 축 모두를 id_channel

   id channel 
    | 43 61 101 631 
--------------------------------- 
43 | NA  6  31  9 
61 | 3 NA  11  1 
101 | 2  1  NA 23 
631 | 10  2  3 NA 

아래 같은 열 및 행. 즉 채널 43을 좋아하는 6 명의 사용자가 채널 61을 좋아하고 채널 1을 좋아하는 사용자 1 명이 채널 61을 좋아한다는 의미입니다.

내가 한 것은 아래 코드에 있습니다. 그것은 작동하지만 원래 테이블에 1.5kk 행이 있기 때문에 코드가 끝나면 약 25 시간이 걸립니다. 이 작업을 수행하는 데 훨씬 더 효율적인 방법이 있다고 가정합니다. f은 길이가 1.5kk이고 데이터 프레임과 같은 원래 데이터이며 lst_users (길이가 650k 행)이고 lst_channel (길이가 50 행)은 id_usersid_channels이라는 고유 한 벡터입니다.

기본적으로 원래 테이블의 서브 세트는 id_user이며 그 다음 각 필드에 대해 데이터 프레임 Channels을 업데이트하는 채널이 루프됩니다.

Channels <- diag(NA, nrow= length(lst_channels), ncol= length(lst_channels)) 

제가 적용과 같은 기능을 사용하여 해결책을 마련하기 위해 노력하고있어 :

for (user in lst_users) { 
    sub <- f[f$id_user == user,] 

    for (j in 1:nrow(sub)) { 
    rindex <- which(lst_channels == sub$id_channel[j]) 
    cindex <- which(lst_channels == unique(sub$id_channel[-j])) 

    Channels[rindex, cindex] <- Channels[rindex, cindex] + 1 
    } 

} 

Channels dataframe은 (매트릭스의 나머지의 대각선 NAS 및 0) 아래와 같이 초기화 , mapply, sapply, ..하지만 실제로 작동하는 무언가가 올 수 없었다. 이 문제에 접근하는 방법에 대한 아이디어가 있습니까?

편집 : @alexis_laz으로

누구의 솔루션 여기에서 구현 될 수 this question에서 비슷한 문제가 지적했다.

해결책 : 용액 Channels <- crossprod(table(f)) 벤치마킹 crossprod(table(f))

+0

끝내 주셔서 감사합니다. 나중에 현재 구현과 비교하여 어떻게 수행했는지 게시 해 보겠습니다. –

+0

@alexis_laz, 분명히 중복 질문, 귀하의 링크는 인접성 테이블의 문제에 대한 완벽한 해답을 제공합니다. – Bernardo

답변

0

는 다음의 결과를 제공한다 : 25시간 + 복용 2- for-loops 가진 것보다

Unit: seconds 
          expr  min  lq median  uq  max neval 
crossprod(table(f[, c(1, 3)])) 6.059346 6.219557 6.31133 6.471866 7.358821 50 

라이트 배 빠른.