2017-03-06 44 views
0

我想獲取滾動方式的過去1到10個事件按列分組的多列。我也希望它非常快,比如在dplyr或data.table中,因爲我想在1,000,000 x 1,000的數據框上運行它。R:獲取多個滾動方式的多個列滯後

開始DF

data.table(a = c("bill", "bob", "bill", "bob", "bill", "bob"), 
     b = c(1,2,1,1,3,2), 
     c = c(2,3,9,1,4,1), 
     d = c(4,5,1,7,3,4)) 

1: bill 1 2 4 
2: bob 2 3 5 
3: bill 1 9 1 
4: bob 1 1 7 
5: bill 3 4 3 
6: bob 2 1 4 

所需DF

我想通過柱帶有1至10中爲每一列的窗口分組僅b和c的滾動平均滯後1行。

 a b c d b_roll1 c_roll1 b_roll2 c_roll2 b_roll3 c_roll3 
1: bill 1 2 4 NA NA   NA  NA  NA  NA 
2: bob 2 3 5 NA NA   NA  NA  NA  NA 
3: bill 1 9 1 1  2   1  2  1  2 
4: bob 1 1 7 2  3   2  3  2  3  
5: bill 3 4 3 1  9   1  5.5  1  5.5  
6: bob 2 1 4 1  1   1  2  1  2    
+1

我不知道我理解你。你正在談論滯後,但滾動手段通常是根據窗口大小,向左,向右或居中計算的。例如,對於[2,3,4],左側2滾動平均值是[NA,2.5,3.5]。然而你的例子顯示了不同的結果。沒有一個滾動的意思,這只是價值本身...你可以更具體地說你在哪裏之後? – Edwin

+0

你是對的愛德​​華。我編輯了所需的數據幀。 – user6452857

回答

2

你們的榜樣結果並沒有什麼太大的意義對我來說,但這裏是你如何可以通過編程產生許多mutate電話的例子。

使用lazyevalRcppRoll的可伸縮的解決方案:

library(tidyverse) 
vars <- c('b', 'c') 
ns <- 1:10 
com <- expand.grid(vars, ns, stringsAsFactors = FALSE) 

dots <- map2(com[[1]], com[[2]], 
      ~lazyeval::interp(~RcppRoll::roll_meanr(x, y, fill = NA), x = as.name(.x), y = .y)) 
names(dots) <- apply(com, 1, paste0, collapse = '_') 

D %>% 
    group_by(a) %>% 
    mutate_(.dots = dots) 

給出:

Source: local data frame [6 x 24] 
Groups: a [2] 

     a  b  c  d `b_ 1` `c_ 1` `b_ 2` `c_ 2` `b_ 3` `c_ 3` `b_ 4` `c_ 4` `b_ 5` `c_ 5` `b_ 6` `c_ 6` `b_ 7` `c_ 7` `b_ 8` `c_ 8` `b_ 9` 
    <chr> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> 
1 bill  1  2  4  1  2  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA 
2 bob  2  3  5  2  3  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA 
3 bill  1  2  1  1  2 1.0  2  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA 
4 bob  1  1  7  1  1 1.5  2  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA 
5 bill  3  4  3  3  4 2.0  3 1.666667 2.666667  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA 
6 bob  2  1  4  2  1 1.5  1 1.666667 1.666667  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA 
# ... with 3 more variables: `c_ 9` <dbl>, b_10 <dbl>, c_10 <dbl> 
1

我還沒有完全關注你。看起來你應用了滯後和滾動均值的組合。對於滾動平均值,這是一個使用dplyrRcppRoll的解決方案。

roll_mean_na <- function(x, lag){ 
    c(rep(NA, lag - 1), RcppRoll::roll_mean(x, lag, align = "left")) 
} 

library(dplyr) 
df %>% group_by(a) %>% 
    mutate(b_2 = roll_mean_na(b, 2), c_2 = roll_mean_na(c, 2), 
      b_3 = roll_mean_na(b, 3), c_3 = roll_mean_na(c, 3), 
      b_4 = roll_mean_na(b, 4), c_4 = roll_mean_na(c, 4)) 
+0

是的。這就是我要的。有沒有辦法讓這個答案更具擴展性?所以如果我將這個應用到100列,我不必寫出每一個變異陳述。 – user6452857

+2

'RcppRoll :: roll_mean'有一個'fill'參數來填充'NA's。 – Axeman