2014-09-03 82 views
10

我想創建一個變量,其中包含組內前一年的變量值。在R中創建不平衡面板數據中的滯後變量

 id date  value 
1  1 1992   4.1 
2  1  NA   4.5 
3  1 1991   3.3 
4  1 1990   5.3 
5  1 1994   3.0 
6  2 1992   3.2 
7  2 1991   5.2 

value_lagged應該丟失時前一年的一個組內的缺失 - 或者是因爲它是一組內的第一個日期(如在第4行,7),或因爲在數據年間隙(如第5行)。此外,當前時間丟失時應丟失value_lagged(如第2行)。

這給:

 id date value value_lagged 
1  1 1992  4.1    3.3 
2  1  NA  4.5    NA 
3  1 1991  3.3    5.3 
4  1 1990  5.3    NA 
5  1 1994  3.0    NA 
6  2 1992  3.2    5.2 
7  2 1991  5.2    NA 

就目前而言,R,我用的是data.table

DT = data.table(id = c(1,1,1,1,1,2,2), 
       date = c(1992,NA,1991,1990,1994,1992,1991), 
       value = c(4.1,4.5,3.3,5.3,3.0,3.2,5.2) 
       ) 
setkey(DT, id, date) 
DT[, value_lagged := DT[J(id, date-1), value], ] 
DT[is.na(date), value_lagged := NA, ] 

它速度快,但它似乎有點容易出錯給我。我想知道是否有更好的選擇使用data.tabledplyr或任何其他包。非常感謝!


Stata,一個會做:

tsset id date 
    gen value_lagged=L.value 
+0

除非特別希望具有缺少**值的行**不具有匹配的滯後值,否則可能意味着使用'is.na(日期)'而不是'is.na(值)' – 2014-09-03 16:28:46

+0

是,更正。謝謝。 – Matthew 2014-09-03 16:29:53

+0

@Matthew看起來像你已經有一個體面的解決方案 - 你想改善什麼呢? – eddi 2014-09-03 17:59:34

回答

6

使用定義的組內的功能tlag通過id

tlag <- function(x, n = 1L, time) { 
    index <- match(time - n, time, incomparables = NA) 
    x[index] 
} 

df %>% group_by(id) %>% mutate(value_lagged = tlag(value, 1, time = date)) 
+0

'N = 2e6L'很小。 0.1 vs 0.23秒並不令人印象深刻..你可以試試'2e7L'還是'2e8L'? – Arun 2014-10-01 14:25:28

+0

確實沒有令人印象深刻。關鍵是要有一個更可讀的解決方案,事實證明,2e6沒有性能成本。我剛剛運行測試:在1e7,lag仍然是*稍微快一點,但純data.table在1e8快兩倍 – Matthew 2014-10-01 14:58:45

+1

*可讀性*的問題在於它不是一個合適的度量;各不相同。我非常喜歡純data.table解決方案,例如:)。 – Arun 2014-10-01 15:01:47

7

這種使用連接我可能會解決:

library(dplyr) 

df <- data.frame(
    id = c(1, 1, 1, 1, 1, 2, 2), 
    date = c(1992, NA, 1991, 1990, 1994, 1992, 1991), 
    value = c(4.1, 4.5, 3.3, 5.3, 3.0, 3.2, 5.2) 
) 


last_year <- df %>% 
    filter(!is.na(date)) %>% 
    mutate(date = date + 1, lagged_value = value, value = NULL) 

df %>% 
    left_join(last_year) 
#> Joining by: c("id", "date") 
#> id date value lagged_value 
#> 1 1 1992 4.1   3.3 
#> 2 1 NA 4.5   NA 
#> 3 1 1991 3.3   5.3 
#> 4 1 1990 5.3   NA 
#> 5 1 1994 3.0   NA 
#> 6 2 1992 3.2   5.2 
#> 7 2 1991 5.2   NA 
3

使用1.9.5,其中加入無需按鍵設置,這可以做如下:

require(data.table) # v1.9.5+ 
DT[!is.na(date), value_lagged := 
     .SD[.(id = id, date = date - 1), value, on = c("id", "date")]] 
# id date value value_lagged 
# 1: 1 1992 4.1   3.3 
# 2: 1 NA 4.5   NA 
# 3: 1 1991 3.3   5.3 
# 4: 1 1990 5.3   NA 
# 5: 1 1994 3.0   NA 
# 6: 2 1992 3.2   5.2 
# 7: 2 1991 5.2   NA 

這是你的想法的變化。訣竅是直接在i中使用is.na(),並在j中使用.SD而不是DT。我已經使用了on=語法,但是當然也可以通過設置鍵來完成同樣的想法。 。

+0

嗨!使用data.table 1.9.5,已安裝11-sep-2015,這會給出錯誤「[.data.table'(.SD,。(id = id,date = date - 1),value,on = c(「id」,:: 未使用的參數(on = c(「id」,「date」))「 – JBJ 2015-09-11 09:05:01

+0

@JBJ使用'remove.packages()'卸載,重新安裝並重試。 – Arun 2015-09-15 09:19:44

相關問題