我正在尝试按类别在滚动窗口中应用函数(例如标准差):
我有以下数据:
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)
我想创建一个新列(例如 sd)来估计猫在两年内的标准偏差。
这是我想到的结果:
关于如何实现这一目标有什么建议吗?
最佳答案
可以通过使用 zoo
包中的 rollapply
来完成:
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
如果您更愿意使用 plyr
函数而不是 by
,也可以使用 ddply
来实现:
df$stdev <- ddply(df, .(cat), summarise,
stdev=c(NA, rollapply(value, width=2, sd)))$stdev
作为一个 lark ,我对上述两种方法以及 @thelatemail 指出的 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
速度并不是真正的问题,但看起来 ave
和 by
版本是实现此目的的最有效方法。
关于r - 将函数应用于 R 面板数据中的滚动窗口,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22775269/