2016-06-30 41 views
5

我想創建多個變量的多個滯後,所以我認爲編寫一個函數會有所幫助。我的代碼引發的警告(「截斷矢量長度1」)和錯誤的結果:調試:函數爲多列創建多個滯後(dplyr)

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或其他的解決方案,也允許實現幾個列的幾個列還有待發現。

編輯2:

對於多個列,並且沒有基團(例如「ID」)以下的溶液似乎非常適合我,由於它的簡單性。該代碼,當然也可以縮短,但一步一步:

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) 
+0

它完美的工作!我只需要閱讀'data.table'就可以正確操作它,併爲其他像我這樣的人 - 認爲不是很熟練的程序員'dplyr'解決方案更容易理解 – yoland

+0

我使用'data'進行了更新。表'的解決方案,如果有很多列你想要做'shift' – akrun

回答

4

我們可以使用shiftdata.table可以採取「N」

library(data.table) 
setDT(df)[order(time), c("a", "b", "c") := shift(x, 1:3) , id][order(id, time)] 

假設多個值,我們需要在這樣做多個列

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也可以在t一起使用他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

謝謝你,這工作,顯然更有效率!我現在將此問題留空 – yoland

+0

dplyr代碼生成6列而不是3,儘管這具有爲新列指定明智名稱的優勢 – yoland

+0

@yoland它只給出3列。請檢查您是使用原始數據集還是使用'data.table'轉換後的數據集。 – akrun