0

これは、以前に投稿した質問の続きです (詳細については、複数の変化する条件を含む行の合計 R data.tableを参照してください)。過去 5 年間に 3 人の被験者がイベントを経験した回数を計算したいと思います。そのため、パッケージrollapplyから使用してローリングウィンドウを合計しています。zooこれは、5 年前の経験が 1 年前の経験と同じくらい重要である (同じ重み付け) と想定しているため、合計に含まれる経験の時間減衰を含めたいと考えています。これは基本的に、5 年前の経験が 1 年前の経験と同じ加重で合計に入らないことを意味します。

私の場合、年齢に依存する減衰を含めたいと思います(他のアプリケーションでは、平方根や平方根などのより高速または低速の減衰が可能ですが)。

たとえば、次のデータがあるとします (わかりやすくするために、以前のデータに基づいています)。

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列のようになります。myres data.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))

どんなポインタでも大歓迎です!

4

1 に答える 1

2

私があなたを正しく理解していれば、単純な合計ではなく、加重合計を実行しようrollapplyとしています。width=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]
于 2014-11-03T06:28:16.023 に答える