debugging:为多列创建多个滞后的函数(dplyr)

时间:2016-06-30 09:36:23

标签: r dplyr

我想创建多个变量的多个滞后,所以我认为编写函数会有所帮助。我的代码抛出一个警告("截断向量到长度1和#34;)和错误的结果:

library(dplyr)
time <- c(2000:2009, 2000:2009)
x <- c(1:10, 10:19)
id <- c(1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2)
df <- data.frame(id, time, x)



three_lags <- function (data, column, group, ordervar) {
  data <- data %>% 
    group_by_(group) %>%
    mutate(a = lag(column, 1L, NA, order_by = ordervar),
            b = lag(column, 2L, NA, order_by = ordervar),
            c = lag(column, 3L, NA, order_by = ordervar)) 
  }

df_lags <- three_lags(data=df, column=x, group=id, ordervar=time) %>%
  arrange(id, time)

我也想知道使用mutate_each是否有更优雅的解决方案,但我也没有做到这一点。我当然可以为每个新的滞后变量编写一个带有一行的长代码,但我想避免这种情况。

编辑:

akrun的dplyr答案有效,但需要很长时间来计算大数据帧。使用data.table的解决方案似乎更有效。因此,dplyr或其他解决方案也允许实现多个列&amp;还有几个滞后。

编辑2:

对于多列而没有组(例如&#34; ID&#34;),由于其简单性,以下解决方案似乎非常适合我。代码当然可以缩短,但是一步一步:

df <- arrange(df, time)

df.lag <- shift(df[,1:24], n=1:3, give.names = T)  ##column indexes of columns to be lagged as "[,startcol:endcol]", "n=1:3" sepcifies the number of lags (lag1, lag2 and lag3 in this case)

df.result <- bind_cols(df, df.lag)

2 个答案:

答案 0 :(得分:4)

我们可以使用shift中的data.tablelibrary(data.table) setDT(df)[order(time), c("a", "b", "c") := shift(x, 1:3) , id][order(id, time)] 可以为&#39; n&#39;

带来多个值
df$y <- df$x
setDT(df)[order(time), paste0(rep(c("x", "y"), each =3), 
                c("a", "b", "c")) :=shift(.SD, 1:3), id, .SDcols = x:y]

假设我们需要在多个列上执行此操作

shift

dplyr也可用于library(dplyr) df %>% group_by(id) %>% arrange(id, time) %>% do(data.frame(., setNames(shift(.$x, 1:3), c("a", "b", "c")))) # id time x a b c # <dbl> <int> <int> <int> <int> <int> #1 1 2000 1 NA NA NA #2 1 2001 2 1 NA NA #3 1 2002 3 2 1 NA #4 1 2003 4 3 2 1 #5 1 2004 5 4 3 2 #6 1 2005 6 5 4 3 #7 1 2006 7 6 5 4 #8 1 2007 8 7 6 5 #9 1 2008 9 8 7 6 #10 1 2009 10 9 8 7 #11 2 2000 10 NA NA NA #12 2 2001 11 10 NA NA #13 2 2002 12 11 10 NA #14 2 2003 13 12 11 10 #15 2 2004 14 13 12 11 #16 2 2005 15 14 13 12 #17 2 2006 16 15 14 13 #18 2 2007 17 16 15 14 #19 2 2008 18 17 16 15 #20 2 2009 19 18 17 16

{{1}}

答案 1 :(得分:0)

也可以创建一个输出tibble的函数:

library(tidyverse)

lag_multiple <- function(x, n_vec){
  map(n_vec, lag, x = x) %>% 
    set_names(paste0("lag", n_vec)) %>% 
    as_tibble()
}

tibble(x = 1:30) %>% 
  mutate(lag_multiple(x, 1:5))
#> # A tibble: 30 x 6
#>        x  lag1  lag2  lag3  lag4  lag5
#>    <int> <int> <int> <int> <int> <int>
#>  1     1    NA    NA    NA    NA    NA
#>  2     2     1    NA    NA    NA    NA
#>  3     3     2     1    NA    NA    NA
#>  4     4     3     2     1    NA    NA
#>  5     5     4     3     2     1    NA
#>  6     6     5     4     3     2     1
#>  7     7     6     5     4     3     2
#>  8     8     7     6     5     4     3
#>  9     9     8     7     6     5     4
#> 10    10     9     8     7     6     5
#> # ... with 20 more rows