2017-12-29 23 views
0

아래는 제 데이터 프레임입니다. 행 이름과 열 이름을가집니다.데이터 프레임에서 연속적인 0의 수

 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 
    row1 0 0 0 1 0 0 1 0 0 0 0 0 0 0 0 
    row2 0 0 0 1 1 1 1 1 1 1 1 1 1 1 0 
나는 각 행의 열을 가로 질러, 마지막 열에서 (연속 제로를 기반으로 열 테스트을 유도 할 수 있습니다. 다음은 예입니다. 첫 번째 행의 경우, 8 연속 제로가 원하는

, 그래서 시험 행의 값이 두 번째 행 8.을해야한다, 결과는 단 하나의 영. (I 15에서 생각과 0이 시작되는 곳까지 다시 가고 싶어).

 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 test 
    row1 0 0 0 1 0 0 1 0 0 0 0 0 0 0 0 8 
    row2 0 0 0 1 1 1 1 1 1 1 1 1 1 1 0 1 
1이어야한다

이것을 달성하는 가장 좋은 방법은 무엇입니까?

rle를 사용
+0

'c (0, 0, 0, 1, 0, 0)'의 결과는 무엇입니까? – PoGibas

+0

2가되어야합니다. – 221B

+0

왜 3이 아닌지 설명 할 수 있습니까? – PoGibas

답변

4

솔루션 :

getConsecZeroRle <- function(x) { 
    foo <- rle(x) 
    foo$lengths[tail(which(foo$values), 1)] 
} 
result <- apply(df[, -1] == 0, 1, function(x) getConsecZeroRle(x)) 
df$test <- as.numeric(result) 
df$test[is.na(df$test)] <- 0 

설명 :

사용 apply이 dataframe의 부분 집합을 반복 할 수 있습니다. 각 행에 대해 연속적인 0의 길이를 계산하고 (rle) tail을 사용하여 마지막 값을 추출하십시오. 0이없는 행은 NA (is.na(df$test) 사용)을 생성하여 0으로 대체합니다.


sum 사용하여 해결 방법 :

getConsecZeroSum <- function(x) { 
    x[1:tail(which(!x), 1)] <- FALSE 
    sum(x) 
} 
df$test <- apply(df[, -1] == 0, 1, function(x) getConsecZeroSum(x)) 

설명 :

추출 마지막 FALSE 각 행의 값과 (x[1:tail(which(!x), 1)] <- FALSE는) 다음에서 0 값을 계산하는 sum를 사용하기 전에 FALSE에 모든 것을 설정 종료.

결과 : 당신은 단순히 동일하지 않는 첫 번째 값의 인덱스를 찾을 수

#  a 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 test 
# 1 row1 0 0 0 1 0 0 1 0 0 0 0 0 0 0 0 8 
# 2 row2 0 0 0 1 1 1 1 1 1 1 1 1 1 1 0 1 
+0

여기 있습니다 내 데이터 프레임 단 하나의 행 (일부 행 이름과 colnames있다) 0 0 0 1 0 0 1 0 0 0 0 0 0 0 결과 정수 (0) 코드를 통해 실행할 때 나는 기대하고있다. 8. – 221B

+0

@ 221B 귀하의 데이터에 맞게 솔루션을 편집했습니다. – PoGibas

+1

이전에 문제가 무엇인지 궁금합니다. – 221B

1

0 (마지막 열에서 시작) 다음 빼기 하나

df$test2 <- apply(df[,ncol(df):1]==0, 1, which.min) - 1 

df 
# 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 test2 
#1 0 0 0 1 0 0 1 0 0 0 0 0 0 0 0  8 
#2 0 0 0 1 1 1 1 1 1 1 1 1 1 1 0  1 

또 다른 대답은

없이이 작업을 수행하는 방법에 대해 궁금해서- 행을 뒤집고 나는 (솔직히 복잡한) Reduce 솔루션을 생각해 냈습니다.

iniCol <- setNames(df[,ncol(df)] == 0, as.numeric(df[,ncol(df)] == 0)) 
df$test2 <- Reduce(function(ini, add) {temp <- ifelse(pmin(as.numeric(names(ini)), add==0) == 0, ini, rowSums(cbind(ini, add == 0))) 
             ini <- setNames(temp, pmin(as.numeric(names(ini)), add==0))}, 
        df[,(ncol(df)-1):1], 
        ini = iniCol) 

이 뒤에 아이디어는 열이 적 0되었는지 여부를 추적 할 names 속성을 사용하는 것입니다 그것을 할 수있는 방법이 있다면 아니 내가 추천 솔루션, 그러나 사람은 내가보고 관심이 있었다. 그때 우리는 세는 것을 멈추고, 그렇지 않으면 세는 것을 계속한다.