2016-10-20 50 views
3

我想安排我的面板數據集以使用常規發生的滯後期的平均值創建新變量。我的示例數據集中的樣子下方,可以使用下面的代碼來訪問如何獲得一個頻率中的滯後期的平均值作爲r中的一個新變量

 Time ID Value1 Value2 
1 Jan-14 A  12  NA 
2 Feb-14 A  14  NA 
3 Mar-14 A  15  NA 
4 Apr-14 A  18  NA 
5 May-14 A  10  NA 
6 Jun-14 A  12 13.67 
7 Jul-14 A  13 15.67 
8 Aug-14 A  14 14.33 
9 Jan-14 B  32  NA 
10 Feb-14 B  14  NA 
11 Mar-14 B  15  NA 
12 Apr-14 B  18  NA 
13 May-14 B  20  NA 
14 Jun-14 B  12 20.33 
15 Jul-14 B  13 15.67 
16 Aug-14 B  14 17.78 

df<-structure(list(Time = structure(c(4L, 3L, 7L, 1L, 8L, 6L, 5L, 
2L, 4L, 3L, 7L, 1L, 8L, 6L, 5L, 2L), .Label = c("Apr-14", "Aug-14", 
"Feb-14", "Jan-14", "Jul-14", "Jun-14", "Mar-14", "May-14"), class = "factor"), 
    ID = structure(c(1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 2L, 2L, 
    2L, 2L, 2L, 2L, 2L, 2L), .Label = c("A", "B"), class = "factor"), 
    Value1 = c(12L, 14L, 15L, 18L, 10L, 12L, 13L, 14L, 32L, 14L, 
    15L, 18L, 20L, 12L, 13L, 14L)), .Names = c("Time", "ID", 
"Value1"), class = "data.frame", row.names = c(NA, -16L)) 

我想創建一個名爲值2考慮對應於之前的4至6個月的每個觀察3個月平均新的變量(這只是例如,我的月度數據集在40個人中共12年,而且我將不得不考慮比3個月,也許是14個月更高的滯後期)。在這裏我需要考慮ID,因爲需要保留面板結構。對於3個月前尚未完成的所有觀察結果,應指示爲NA。例如Jun_14_A應該從Mar_14_AJan_14_A。 (12 + 14 + 15)/ 3 = 13.67

我提到了一些例子here,但是那些沒有提供我正在尋找的東西,特別是滯後的平均值,並且在沒有前3個完整的月份時指示爲NA s。

預先感謝您的任何幫助

回答

2

下面是使用只是data.table另一種方式,而且是shift功能與Reduce組合(這是this幾乎重複)

library(data.table) 
setDT(df)[, Value2 := Reduce(`+`, shift(Value1, 3:5))/3, by = ID] 
df 
#  Time ID Value1 Value2 
# 1: Jan-14 A  12  NA 
# 2: Feb-14 A  14  NA 
# 3: Mar-14 A  15  NA 
# 4: Apr-14 A  18  NA 
# 5: May-14 A  10  NA 
# 6: Jun-14 A  12 13.66667 
# 7: Jul-14 A  13 15.66667 
# 8: Aug-14 A  14 14.33333 
# 9: Jan-14 B  32  NA 
# 10: Feb-14 B  14  NA 
# 11: Mar-14 B  15  NA 
# 12: Apr-14 B  18  NA 
# 13: May-14 B  20  NA 
# 14: Jun-14 B  12 20.33333 
# 15: Jul-14 B  13 15.66667 
# 16: Aug-14 B  14 17.66667 
1

一種方式做到這一點,它不精,所以也許有人(我,如果我得到的時間)會後,有更優雅的解決方案:
第一件事是將您的df$time轉換爲實際日期。

library(zoo) 
df$Time=as.yearmon(as.character(df$Time),"%b-%y") 
library(dplyr) 
df%>% 
    group_by(ID)%>% 
    mutate(Value2 = (lag(Value1, 3) + lag(Value1, 4) + lag(Value1, 5))/3) 

    Time  ID Value1 Value2 
    <fctr> <fctr> <int> <dbl> 
1 Jan-14  A  12  NA 
2 Feb-14  A  14  NA 
3 Mar-14  A  15  NA 
4 Apr-14  A  18  NA 
5 May-14  A  10  NA 
6 Jun-14  A  12 13.66667 
7 Jul-14  A  13 15.66667 
8 Aug-14  A  14 14.33333 
9 Jan-14  B  32  NA 
10 Feb-14  B  14  NA 
11 Mar-14  B  15  NA 
12 Apr-14  B  18  NA 
13 May-14  B  20  NA 
14 Jun-14  B  12 20.33333 
15 Jul-14  B  13 15.66667 
16 Aug-14  B  14 17.66667 

我創建與滯後3,4和5 3可變並且簡單地計算出的平均值,任何NA(未3個完整月份)將返回NA。

+0

感謝這些答案。所有的工作都完全符合我的數據集。但我選擇數據表的答案與轉移和減少。 – sriya

+0

建議'mutate(Value2 =(lag(Value1,3)+ lag(Value1,4)+ lag(Value1,5))/ 3)'在這種情況下'select'不需要。 –

+0

好的建議,我編輯。 – Haboryme

1

我們可以嘗試:

library(data.table) 
setDT(df) 
f <- function(x) if(anyNA(x[1:6])) NA else mean(x[1:3]) 
df[, Value2 := zoo::rollapply(Value1, 6, f, align = "right", partial = TRUE), by = ID] 

> df 
     Time ID Value1 Value2 
1: Jan-14 A  12  NA 
2: Feb-14 A  14  NA 
3: Mar-14 A  15  NA 
4: Apr-14 A  18  NA 
5: May-14 A  10  NA 
6: Jun-14 A  12 13.66667 
7: Jul-14 A  13 15.66667 
8: Aug-14 A  14 14.33333 
9: Jan-14 B  32  NA 
10: Feb-14 B  14  NA 
11: Mar-14 B  15  NA 
12: Apr-14 B  18  NA 
13: May-14 B  20  NA 
14: Jun-14 B  12 20.33333 
15: Jul-14 B  13 15.66667 
16: Aug-14 B  14 17.66667 
+0

我在這裏學習一個新的函數rollapply。謝謝 – sriya

2

嘗試從動物園rollapplyr。的list(-3:-5)寬度意味着它將使用哪個偏移-3的組件,-4和-5從當前點在每次迭代:

library(zoo) 
roll <- function(x) rollapplyr(x, list(-3:-5), mean, fill = NA) 
transform(df, Value2 = ave(Value1, ID, FUN = roll)) 

給出以下的數據幀:

 Time ID Value1 Value2 
1 Jan-14 A  12  NA 
2 Feb-14 A  14  NA 
3 Mar-14 A  15  NA 
4 Apr-14 A  18  NA 
5 May-14 A  10  NA 
6 Jun-14 A  12 13.66667 
7 Jul-14 A  13 15.66667 
8 Aug-14 A  14 14.33333 
9 Jan-14 B  32  NA 
10 Feb-14 B  14  NA 
11 Mar-14 B  15  NA 
12 Apr-14 B  18  NA 
13 May-14 B  20  NA 
14 Jun-14 B  12 20.33333 
15 Jul-14 B  13 15.66667 
16 Aug-14 B  14 17.66667 

注意:儘管我們沒有做出改變,因爲不需要回答問題,請注意,您可能希望使用動物園的"yearmon"類作爲第一列。有了這個班級年/月的值排序正確,但很好地顯示。也就是,

transform(df, Time = as.yearmon(Time, "%b-%y"), Value2 = ...as above...) 
相關問題