2017-06-29 38 views
2

我有一個DF:df R中每x行的總和,僅輸出第x行。 [R

df <- data.frame(x = c(1,2,3,4,5,6,7,8,9,10,11,12,13), 
        y = c(0,0,2,0,1,0,0,0,0,3,0,4,0)) 

我在精確時刻尋找每4行的總和(時刻4後),這應該是輸出:

x y z 
1 0 0 
2 0 0 
3 2 0 
4 0 2 
5 1 0 
6 0 0 
7 0 0 
8 0 1 
9 0 0 
10 3 0 
11 0 0 
12 4 7 
13 0 0 

隨着dplyr我能夠用以下結果創建以下代碼。

a <- df %>% 
    dplyr::mutate(b = gl(ceiling(nrow(x)/4), 4, nrow(x))) %>% 
    dplyr::group_by(b) %>% 
    dplyr::mutate(sum = sum(amount)) 

x y z 
1 0 2 
2 0 2 
3 2 2 
4 0 2 
5 1 1 
6 0 1 
7 0 1 
8 0 1 
9 0 7 
10 3 7 
11 0 7 
12 4 7 
13 0 0 

但我不能夠刪除的數量,並與除第4行0取代他們,但問題是,如果我有一段0的它重複。

+0

u能顯示預期的輸出 – akrun

+0

我編輯的問題 – user5424264

+0

難道你的意思是'DF%>% sum(y),0))%> mutate(sum = if_else(row_number()== n(),sum(y),0))'group_by(b = gl(ceiling(n()/ 4),4,n())) – akrun

回答

4

通過用gl創建「B」分組後,我們通過得到「Y」的sum和與邏輯矢量(row_number()==n()),以便乘以創建「z」的列,除了最後一行,所有其它元素變爲0

library(dplyr) 
df %>% 
    group_by(b = gl(ceiling(n()/4), 4, n())) %>% 
    mutate(z = sum(y) * (row_number()== n())) %>% 
    ungroup() %>% 
    select(-b) 
# A tibble: 13 x 3 
#  x  y  z 
# <dbl> <dbl> <dbl> 
# 1  1  0  0 
# 2  2  0  0 
# 3  3  2  0 
# 4  4  0  2 
# 5  5  1  0 
# 6  6  0  0 
# 7  7  0  0 
# 8  8  0  1 
# 9  9  0  0 
#10 10  3  0 
#11 11  0  0 
#12 12  4  7 
#13 13  0  0 

如果我們需要一個外部封裝,高效RcppRoll可以使用,並且可以容易地實現輸出以及

library(RcppRoll) 
with(df, round(roll_sumr(y, n = 4, by=4, fill = 0))) 
#[1] 0 0 0 2 0 0 0 1 0 0 0 7 0 
6

這可以很容易地rollapplyzoo包裝來實現,即

library(zoo) 

rollapply(df$y, 4, by = 4, sum, fill = 0, align = 'right') 
#[1] 0 0 0 2 0 0 0 1 0 0 0 7 0 
2

在基礎R

df$z = 0 
replace(df$z, 
     seq_along(df$z)%%4 == 0, 
     sapply(split(df$y, floor(seq_along(df$y)/4.01)), sum)) 
# [1] 0 0 0 2 0 0 0 1 0 0 0 7 0 
#Warning message: 
#In replace(df$z, seq_along(df$z)%%4 == 0, sapply(split(df$y, #floor(seq_along(df$y)/4.01)), : 
# number of items to replace is not a multiple of replacement length