2013-03-17 5 views
11

나는 이것이 상당히 쉬운 질문 인 것처럼 느껴지지만 내 인생에서 나는 대답을 찾지 못하는 것 같습니다. 나는 꽤 표준적인 데이터 프레임을 가지고 있으며, 어떤 값 (정확한 값 또는 그 값보다 큰 값)에 도달 할 때까지 값의 열을 합산하는 것이고, 그 시점에서 1을 새로운 열 (레이블이 붙은 유지)를 수행하고 0에서 합계를 다시 시작합니다.누적 합계가 최대 값에 도달 할 때까지 다음 행에서 0부터 반복하십시오.

분, 열 및 누적 합계 열의 차이가 있습니다 (사용하는 예는 실제 전체 데이터 집합보다 훨씬 깔끔합니다)

minutes  difference  keep  difference_sum 
1052991158  0   0   0 
1052991338  180   0   180 
1052991518  180   0   360 
1052991698  180   0   540 
1052991878  180   0   720 
1052992058  180   0   900 
1052992238  180   0   1080 
1052992418  180   0   1260 
1052992598  180   0   1440 
1052992778  180   0   1620 
1052992958  180   0   1800 

차이 합 열은 코드

caribou.sub$difference_sum<-cumsum(difference) 
산출 하였다

위의 코드를 실행하려면 합계 값이 1470이나 그보다 큰 숫자에 도달하면 유지 열에 1을 넣은 다음 나중에 다시 계산을 다시 시작하고 데이터 세트.

미리 감사드립니다. 추가 정보가 필요하면 알려주십시오.

Ayden는

+3

1470에 도달하면 'difference_sum'이 0으로 재설정됩니까? 'difference_sum '이 임계 값을 넘어갈 때를 포함하여 약간 더 긴 예제 세트가 도움이 될 것입니다. – alexwhan

+0

아니, 내가하려고하는 것, 차감 값 열은 현재 caribou.sub difference_sum <-cumsum (차이) 코드로 계산됩니다. 데이터 세트를 계속 진행하고 있습니다. – HeidelbergSlide

+0

그렇지만 임계 값을 초과 한 후에는 다음 임계 값을 계산하는 방법에 대해 어떻게 생각하십니까? 1470 년에 흑자를 사용 했습니까? 다음 행에서 0으로 시작 하시겠습니까? – alexwhan

답변

7

나는 상자 밖으로 그렇게 할 수있는 기능을 생각할 수 없다,이 for 루프를 함께 할 최고라고 생각합니다. 다음은 당신이 원하는 것을해야합니다 (나는 당신을 정확하게 이해하는 경우).

current.sum <- 0 
for (c in 1:nrow(caribou.sub)) { 
    current.sum <- current.sum + caribou.sub[c, "difference"] 
    carribou.sub[c, "difference_sum"] <- current.sum 
    if (current.sum >= 1470) { 
     caribou.sub[c, "keep"] <- 1 
     current.sum <- 0 
    } 
} 

정확히 원하는 것이 아닌 경우 자유롭게 의견을 말하십시오. 그러나 alexwhan이 지적한 바와 같이, 귀하의 설명은 완전히 명확하지 않습니다.

+0

아, 완벽합니다. 맞습니다. 내가해야만하는 것은 복사하여 붙여 넣기뿐이었습니다. 매우 감사합니다. – HeidelbergSlide

+0

첫 번째 행은 180입니다. 0일까요? – Aaron

+0

예에서? 0이어야합니다. 방금 변경했습니다. – HeidelbergSlide

7

은 당신의 가정 data.framedf입니다 :

df$difference_sum <- c(0, head(cumsum(df$difference), -1)) 
# get length of 0's (first keep value gives the actual length) 
len <- sum(df$difference_sum %/% 1470 == 0) 
df$keep <- (seq_len(nrow(df))-1) %/% len 
df <- transform(df, difference_sum = ave(difference, keep, 
      FUN=function(x) c(0, head(cumsum(x), -1)))) 

#  minutes difference keep difference_sum 
# 1 1052991158  180 0    0 
# 2 1052991338  180 0   180 
# 3 1052991518  180 0   360 
# 4 1052991698  180 0   540 
# 5 1052991878  180 0   720 
# 6 1052992058  180 0   900 
# 7 1052992238  180 0   1080 
# 8 1052992418  180 0   1260 
# 9 1052992598  180 0   1440 
# 10 1052992778  180 1    0 
# 11 1052992958  180 1   180 
+2

이것은 제가 가고있는 곳입니다[email protected] - 이것은 루프보다 현저하게 빠릅니다. – alexwhan

+0

"zero from repeat"가 없습니다. 그것은 다른 대답에서 갈라집니다. –

+0

@MatthewLundberg, op는 올바른 cumsum 값에도 관심이 있다는 뜻입니까? 방금 '계산'이라고 생각 했나요? – Arun

1

그 다음 0이되어야한다면 난 아직도 합이 다시 시작해야하는 경우에 대해 이해하지 않습니다. 원하는 결과가 크게 도움이됩니다.

그럼에도 불구하고 간단히 색인 생성 및 뺄셈이이를 수행하는 간단한 방법이라고 생각할 수는 없습니다. 아래 코드는 @ Henrik의 솔루션과 동일한 결과를 제공합니다.

df$difference_sum <- cumsum(df$difference) 
step <- (df$difference_sum %/% 1470) + 1 
k <- which(diff(step) > 0) + 1 
df$keep <- 0 
df$keep[k] <- 1 
step[k] <- step[k] - 1 
df$difference_sum <- df$difference_sum - c(0, df$difference_sum[k])[step] 
+0

이것은 정말 가깝지만, (내가 이것을 이해하고 매우 틀릴 수도 있기 때문에) 전체 차이 열의 누적 값을 사용하기 때문에 이전 선택에서 초과 된 값이 다음 선택으로 통합되므로 하나의 행이 발생합니다 곧 (첫 번째 선택된 값은 분 1620이지만 150 분이 지나면 무시해야하지만 다음 선택을 위해 사용됩니다. 그래서 cumsum이 실제로 150 분보다 더 많이 말하기 때문에 다음 선택은 1440 분에 발생합니다) . 말이 돼? 도와 줘서 고마워! – HeidelbergSlide

+0

아, 알겠습니다. 네, 맞습니다 (제 대답이 옳지 않다는 것을 의미합니다). 다시 말하면, 원하는 결과물을 가진 더 큰 예제가 도움이 될 것입니다. 그러나 문제가 해결 된 것처럼 들리므로이 시점에서 귀찮은 일은 없을 것입니다. – Aaron