3

カテゴリごとに、ローリングウィンドウに関数(標準偏差など)を適用しようとしています:

次のデータがあります。

cat = c("A", "A", "A", "A", "B", "B", "B", "B") 
year = c(1990, 1991, 1992, 1993, 1990, 1991, 1992, 1993) 
value = c(2, 3, 5, 6, 8, 9, 4, 5) 
df = data.frame(cat, year, value)

cat ごとに 2 年間のウィンドウの標準偏差を推定する新しい列 (sd など) を作成したいと思います。

これが私が考えている結果です:

ここに画像の説明を入力

これを達成する方法について何かアドバイスはありますか?

4

1 に答える 1

2

パッケージrollapplyから使用して行うことができます:zoo

library(zoo)

cat = c("A", "A", "A", "A", "B", "B", "B", "B") 
year = c(1990, 1991, 1992, 1993, 1990, 1991, 1992, 1993) 
value = c(2, 3, 5, 6, 8, 9, 4, 5) 
df = data.frame(cat, year, value)

df$stdev <- unlist(by(df, df$cat, function(x) {
  c(NA, rollapply(x$value, width=2, sd))
}), use.names=FALSE)

print(df)
##   cat year value     stdev
## 1   A 1990     2        NA
## 2   A 1991     3 0.7071068
## 3   A 1992     5 1.4142136
## 4   A 1993     6 0.7071068
## 5   B 1990     8        NA
## 6   B 1991     9 0.7071068
## 7   B 1992     4 3.5355339
## 8   B 1993     5 0.7071068

よりも関数をddply使用したい場合は、次のようにすることもできます。plyrby

df$stdev <- ddply(df, .(cat), summarise, 
                  stdev=c(NA, rollapply(value, width=2, sd)))$stdev

ヒバリとして、上記の2つの方法と、この回答の下のコメントスレッドで@thelatemailによって指摘された方法system.timeを(複数回)比較しました(データフレームの「新しい」コピーから始めます)。ave

df <- data.frame(cat, year, value)
system.time(df$stdev <- with(df, ave(value, cat, FUN=function(x) c(NA, rollapply(x, width=2, sd)))))

df <- data.frame(cat, year, value)
system.time(df$stdev <- unlist(by(df, df$cat, function(x) c(NA, rollapply(x$value, width=2, sd))), use.names=FALSE))

df <- data.frame(cat, year, value)
system.time(df$stdev <- ddply(df, .(cat), summarise, stdev=c(NA, rollapply(value, width=2, sd)))$stdev)

aveメソッドとメソッドはどちらも次の値をby取ります。

   user  system elapsed 
  0.002   0.000   0.002 

ddplyバージョンは次のとおりです。

   user  system elapsed 
  0.004   0.000   0.004 

ここで実際に速度が問題になるわけではありませんが、avebyバージョンがこれを行う最も効率的な方法のようです。

于 2014-04-01T01:54:00.003 に答える