2017-01-14 4 views
0

날짜와 값이있는 데이터 프레임이 있고 양수 만의 누적 값과 음수 값의 누적 값을 원합니다. 날짜가 같은 날짜가 여러 번 있고 며칠이 누락되는 경우가 있습니다 (값이 없으면 행이 없음)날짜순으로 정렬 된 데이터 프레임의 특정 숫자 누적 합계

처음에는 방금 누적 합계를 테스트했습니다.

:
df$cumsum <- cumsum(df$values) 
# or 
df$cumsum <- ave(df$values, FUN=cumsum) 
# Should cumulate by date but did not in right order 
df$cumsum <- cumsum(df[order(df$date, df$values), "values"]) 

마지막으로 (일을 내가 dataframe에에하고 싶었던대로 정말하지만 않습니다) 내가 원하는대로 첫 번째 단계를 수행하는 솔루션을 발견 :이 누적하지만 날짜의 순서에 있었다
dt <- data.table(df) 
dt[order(date), cumsum := cumsum(values)] 

위대한, 그러나 필터링 값> 0 모든 시도가 작동하지 않았다. 마지막으로 데이터를 부분 집합하여 결과를 얻었지만 실제로 원하는 것은 아닙니다.

df["cumsum_pos"] = df["values"][df["values"] > 0].cumsum() 
df["cumsum_neg"] = df["values"][df["values"] < 0].cumsum() 

/편집

df <- data.frame(date = as.Date(c("2016-12-08", "2016-12-07", "2016-12-05", "2017-01-05", 
            "2017-01-10", "2017-01-11", "2017-01-11")), 
       values = c(10, -10, 5, 5, -7, 8, 8)) 

# just the cumsum 
# expected output = c(5, -5, 5, 10, 3, 11, 19) 

df$cumsum <- cumsum(df$values) 
# output = c(10, 0, 5, 10, 3, 11, 19) 

df$cumsum <- ave(df$values, FUN=cumsum) 
# output = c(10, 0, 5, 10, 3, 11, 19) 

df$cumsum <- cumsum(df[order(df$date, df$values), "values"]) 
# output = c(5, -5, 5, 10, 3, 11, 19) correct in this example 
# doesn't work with dates in a different order 2016-12-31, 2016-12-30, ... 2015-12-31, 2015-12-30 

# Now for just the positives 
# expected output = c(10, 0, 5, 15, 15, 23, 31) 
df$cumsum.pos[df$values > 0] <- cumsum(df[order(df$date, df$values), "values"][df$values > 0]) 
# output = c(5, NA, 15, 20, NA, 28, 36) 

# And then the same with just the negatives 

/편집

니콜라 :

dt.pos <- data.table(subset(df, values> 0)) 
dt.pos[order(date), cumsum := cumsum(values)] 

dt.neg <- data.table(subset(df, values < 0)) 
dt.neg[order(date), cumsum := cumsum(values)] 

나는 (정렬 된 데이터 프레임) 파이썬 해당하는만큼 간단 뭔가를 찾고 있어요 주석은 올바른 출력을 생성하지 않습니다.

df<-df[order(df$date),] 
# values = c(5, -10, 10, 5, -7, 8, 8) 
# expected output = c(5, 5, 15, 20, 20, 28, 36) 
df$cumsum<-ave(df$values,df$values>0,FUN=cumsum) 
# output = c(5, -10, 15, 20, -17, 28, 36) 
+1

작은 재현 예를 예상 출력 – akrun

+1

먼저 주문하세요 data.frame 보여주십시오 'DF <-df [순서 (안양 $ 날짜)]'다음'ave'를 사용 : df $ cumsum <-ave (df $ value, df $ value> 0, FUN = cumsum)' – nicola

+0

불행히도 그것은 내가 원한 것을 정확하게주지 못한다. 그것이 올바른 방향으로의 한 걸음이라고 생각합니다. – sezi80

답변

1

사용할 수 있습니다.

library(data.table) 
df <- as.data.table(df) 

# Order by date 
df <- df[order(date)] 

# Perform the cumsum for positives and negatives separately 
df[, expected := cumsum(values), by = sign(values)] 

# Just for the negatives, get the previous positive value 
df[, expected := ifelse(values > 0, expected, c(0, expected[-.N]))] 

print(df) 

     date values expected 
1: 2016-12-05  5  5 
2: 2016-12-07 -10  5 
3: 2016-12-08  10  15 
4: 2017-01-05  5  20 
5: 2017-01-10  -7  20 
6: 2017-01-11  8  28 
7: 2017-01-11  8  36 

음수 값이 두 개 이상 계속되면 작업을 반복해야합니다. 예를 들어, 데이터 프레임이 하나 인 경우 : 위의 코드의

df <- data.frame(date = as.Date(c("2016-12-08", "2016-12-07", "2016-12-05", "2017-01-05","2017-01-10", "2017-01-10", "2017-01-11", "2017-01-11")), 
values = c(10, -10, 5, 5, -7, -15, 8, 8)) 

하나의 단일 실행은 다음과 같은 출력을 생성합니다 :

  date values expected 
1: 2016-12-05  5  5 
2: 2016-12-07 -10  5 
3: 2016-12-08  10  15 
4: 2017-01-05  5  20 
5: 2017-01-10  -7  20 
6: 2017-01-10 -15  -17 
7: 2017-01-11  8  28 
8: 2017-01-11  8  36 

값 -17 잘못된 것입니다. 이 문제를 피하기 위해 음수 값이 없을 때까지 프로세스를 반복 할 수 있습니다. 그래서 전체 코드는 다음과 같습니다

df <- df[order(date)] 
df[, expected := cumsum(values), by = sign(values)] 

# If there are negative values, repeat the process 
while(length(which(df$expected < 0))){ 
    df[, expected := ifelse(values > 0, expected, c(0, expected[-.N]))] 
} 

print(df) 
     date values expected 
1: 2016-12-05  5  5 
2: 2016-12-07 -10  5 
3: 2016-12-08  10  15 
4: 2017-01-05  5  20 
5: 2017-01-10  -7  20 
6: 2017-01-10 -15  20 
7: 2017-01-11  8  28 
8: 2017-01-11  8  36 
+0

노력해 주셔서 감사합니다. 그러나 이것은 제가 이미 해결책을 제시 한 첫 번째 부분이었습니다. 나는 긍정적 인 가치만을위한 cumsum이 필요합니다. – sezi80

+0

@ sezi80 죄송합니다. 질문을 이해하지 못했습니다. 나는 대답을 업데이트했고, 그것은 긍정적 인 것과 네가티브를위한 cumsum을 따로 따로 계산한다. 이것은 당신의 예상 결과입니까? –

+0

제 초기 게시물은 충분히 설명력이없는 것 같습니다. 나는 긍정적 인 cumsum을 원하기 때문에'geom_line()'이 곧바로 진행될 것입니다. 데이터를 서브 세트하지 않고. '예상 출력 = c (5, 5, 15, 20, 20, 28, 36)' – sezi80