2014-07-26 1 views
0
나는 data.table의 행에 연속 감소의 가장 긴 수를 계산하는 좋은 방법을 찾고 있어요


은 내가 R.에서 R 길이

(패키지 버전 1.9.2)을 행 시퀀스를 감소 끔찍하게 잃어버린 어떤 도움이 많이 감사합니다. 예를 들어, 감소는 값이 이전 값 (< =)보다 작거나 같은 경우입니다.

다음은 내가 다루는 데이터의 장난감 샘플입니다. 나는 또한 지금까지 최선의 시도를 내려 놓았습니다. 솔직히 말하면 끔찍하게 잘못되어 오류를 보냈습니다. 내 시도는 2를 사용합니다. 나는 2 년 동안 루프를 사용합니다. 이후 루프를 사용하는 것이 좋습니다. R과 비슷한 사이트를 검색해 보았지만 행운이 없었습니다. 실제로 내 전체 데이터 테이블에있는 행의 수는 1 백만 이상이며 내가 가지고있는 열 수는 원하는 출력 코드의 하단에 나타납니다 (17)

library(data.table) 

TEST_DF <- data.table(COL_1 = c(5,2,3,1), COL_2 = c(1,0,4,2), 
         COL_3 = c(0,1,6,3), COL_4 = c(0,0,0,4)) 

TEST_DF$COUNT <- as.numeric(0) 

for(i in 1:NROW(TEST_DF)) 
{ 
    for (j in 1:(NCOL(TEST_DF) - 1)) 
    { 
    TEST_DF$COUNT[j] <- if (TEST_DF[i, j, with = FALSE] >= 
          TEST_DF[i, j + 1, with = FALSE]) 
         { 
          TEST_DF$COUNT[j] + 2 
         } 
    } 
} 

DESIRED <- data.table(COL_1 = c(5,2,3,1), COL_2 = c(1,0,4,2), 
         COL_3 = c(0,1,6,3), COL_4 = c(0,0,0,4), 
         COUNT = c(4,2,1,0)) 

입니다. 가장 긴 축소 시퀀스에 4 개의 "COL"열이 나타나므로 첫 번째 행에 대한 COUNT 열의 값은 4가됩니다. 두 번째 행에는 처음 2 개 열과 마지막 2 개에 감소가 있지만 그 사이에 COUNT는 2의 값을 얻습니다. 마지막 열에는 COL_3에서 COL_4로 감소하므로 COUNT는이 행에 대해 2의 값을 갖습니다. 마지막 행과 같은 감소가없는 행에서는 COUNT에 0 값이 있습니다.

추가 설명이나 정보가 필요한지 알려주세요.

미리 감사드립니다.

+1

:'sapply (1 : nrow를 (tmp) = 1); tmp <- if (length (tmp) = (tmp) = 0) = ncol (TEST_DF) - 1) 0 else tmp; min (ncol (TEST_DF), tmp)})''4 2 1 0''if' 행은 마지막 행의 특별한 경우를 처리하기 위해 거기에 있습니다. – rawr

+0

도움을 요청 건배 Rawr. 당신의 기능은 작동하지만 @ Andrie 's는 그가 배치 한 방식으로 더 쉽게 이해할 수 있습니다. –

답변

1

당신은 실행 길이를 추출하는 기능을 구축하기 위해 기능 diff()rle()를 사용할 수 있습니다. 그런 다음 데이터 행에 걸쳐 apply()를 사용

이 그래서 대답으로 게시하고 싶지 않아하지만 어쩌면 사람이 더 우아한 뭔가 함께 올 것이다 조금 못생긴 가지고
foo <- function(x) { 
    runs <- rle(c(x[2] <= x[1], diff(x) <= 0)) 
    if(all(runs$value == 0)) 0 else max(runs$lengths[runs$value == 1]) 
} 

apply(TEST_DF, 1, foo) 

[1] 4 2 1 0 
+0

감사합니다 Andrie. 그 트릭을했고 당신의 솔루션은 매우 깔끔하고 이해하기 쉽습니다. 건배 :) –

0

나는 당신이 찾고있는 것을 달성하기 위해 하나의 네 개의 루프와 함께 적용했다. apply는 각 행에 대해 작동하고 for 루프는 연속적인 열을 비교합니다.

COUNT <- rep(0,4) 
for (i in 1:(ncol(TEST_DF)-1)) { 
    COUNT<-COUNT+apply(TEST_DF,1,function(x) ifelse(x[i]>=x[i+1],1,0)) 
} 

이렇게하면 첫 번째 행에 3 개의 축소가 생성되므로 3, 2, 1, 0이 생성됩니다. 마지막 열은 비교할 것이 없으므로 세 가지 비교 만있을 수 있습니다. 왜 네가 4가되기를 원하는지 모르겠다.

당신은 당신의 원래 테이블의 일부로 계산하려면 다음

TEST_DF$COUNT<-COUNT