2014-11-03 31 views
0

這是我之前發佈的問題的後續問題(有關更多詳細信息,請參見Sum over rows with multiple changing conditions R data.table)。我想計算3名受試者在過去5年中經歷過多少次事件。因此,使用zoo包中的rollapply來總結滾動窗口。這假設5年前的經驗與1年前的經驗(同樣的權重)同樣重要,所以現在我想包括輸入總和的經驗的時間衰減。這基本上意味着5年前的經驗沒有與1年前的經驗具有相同的權重。隨着時間的推移累計行數(rollapply)

我的情況我想包括年齡依賴衰減(即使對於其他應用程序更快或更慢的衰減,如平方根或正方形也是可能的)。

例如讓我們假設我有以下數據(我建立在以前的數據爲清楚起見):

mydf <- data.frame (Year = c(2000, 2001, 2002, 2004, 2005, 
         2007, 2000, 2001, 2002, 2003, 
         2003, 2004, 2005, 2006, 2006, 2007), 
       Name = c("Tom", "Tom", "Tom", "Fred", "Gill", 
         "Fred", "Gill", "Gill", "Tom", "Tom", 
         "Fred", "Fred", "Gill", "Fred", "Gill", "Gill")) 

# Create an indicator for the experience 
mydf$Ind <- 1 

# Load require packages 
library(data.table) 
library(zoo) 

# Set data.table 
setDT(mydf) 
setkey(mydf, Name,Year) 

# Perform cartesian join to calculate experience. I2 is the new experience indicator 
m <- mydf[CJ(unique(Name),seq(min(Year)-5, max(Year))),allow.cartesian=TRUE][, 
     list(Ind = unique(Ind), I2 = sum(Ind,na.rm=TRUE)), 
     keyby=list(Name,Year)] 

# This is the approach I have been taking so far. Note that is a simple rolling sum of I2 
m[,Exp := rollapply(I2, 5, function(x) sum(head(x,-1)), 
       align = 'right', fill=0),by=Name] 

所以,現在的問題是,我怎麼能包括年齡依賴性衰變成這個計算。爲了模擬這一點,我需要在經驗進入總和之前,根據經驗的年齡劃分經驗。

我一直在試圖得到它使用的東西沿着這些線路的工作:

m[,Exp_age := rollapply(I2, 5, function(x) sum(head(x,-1)/(tail((Year))-head(Year,-1))), 
        align = 'right', fill=0),by=Name] 

但它不工作。我認爲我的主要問題是,我無法獲得正確的年齡,因此我可以按年齡劃分總和。結果應該看起來像Exp_age列在myresdata.frame下面

myres <- data.frame(Name = c("Fred", "Fred", "Fred", "Fred", "Fred", 
         "Gill", "Gill", "Gill", "Gill", "Gill", "Gill", 
         "Tom", "Tom", "Tom", "Tom", "Tom"), 
       Year = c(2003, 2004, 2004, 2006, 2007, 2000, 2001, 2005, 
         2005, 2006, 2007, 2000, 2001, 2002, 2002, 2003), 
       Ind = c(1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1), 
       Exp = c(0, 1, 1, 3, 4, 0, 1, 1, 1, 2, 3, 0, 1, 2, 2, 4), 
       Exp_age = c(0, 1, 1, 1.333333333, 1.916666667, 0, 1, 0.45, 
          0.45, 2.2, 2, 0, 1, 1.5, 1.5, 2.833333333)) 

任何指針將不勝感激!

回答

2

如果我正確理解你,你正在嘗試做rollapplywidth=5而不是做一個簡單的總和,你想做一個加權總和。權重是相對於5年窗口的經驗年齡。我會這樣做:首先在您的data.table中設置密鑰,使其具有適當的遞增順序Name,然後您知道x變量中的最後一項是最年輕的,第一項是最早的項目(您在代碼中執行此操作已經)。我無法確定你想要體重去哪個方向(最年輕有最大體重或最老),但你得到的重點:

setkey(m, Name, Year) 
my_fun = function(x) { w = 1:length(x); sum(x*w)} 
m[,Exp_age:=rollapply(I2, width=5, by=1, fill=NA, FUN=my_fun, by.column=FALSE, align="right") ,by=Name] 
+0

非常感謝您的快速反應。你是對的,這是我試圖達到的目標。我調整了函數來滿足我的需求,就像my_fun = function(x){w = length(x):1; sum(x/w)}'這似乎返回正確的值(或至少一些),但Exp_age列未按預期對齊。另外我得到3個警告信息:'1:在''[.data.table''(m,,'':=''(Exp_age,rollapply(I2,width = 5,by = 1,: Supplied 9項目在'Exp_age'列中被分配到13號大小的組1(再循環剩餘的4項)'(接下來的評論) – Rkook 2014-11-03 07:56:01

+0

'2:在''[.data.table''(m,,' ':=''(Exp_age,rollapply(I2,width = 5,by = 1,: )提供了9個項目,分配給'Exp_age'列中的13號大小的組2(可回收剩下的4項) 3 :在''[.data.table''(m,,'':=''(Exp_age,rollapply(I2,width = 5,by = 1,: )中提供了9項要分配給13號組3在'Exp_age'一欄(回收剩下的4個項目)。'任何想法可能會發生什麼? – Rkook 2014-11-03 07:58:14

+0

我想我發現什麼地方出了問題,我必須允許'partial = TRUE',所以代碼是:'m [,Exp_age:= rollapply(I2,width = 5,by = 1,FUN = my_ fun,by.column = FALSE,align =「right」,partial = TRUE),by = Name]'。然後,我只需要延遲體驗變量以達到期望的結果(儘管我無法一氣之下做到這一點)。 – Rkook 2014-11-03 11:08:27

相關問題