我在下面有一个循环,它将两个新列分配给数据表,使用最近21天的数据,每天10个样本。它工作但效率很低,我想帮助如何矢量化移动子集。我有一种感觉"申请"功能涉及,但我不知道如何使用不常数的子集。下面是我的循环 - 我首先为新列分配零,因为我认为就地修改值比每次迭代添加新值要快。
data$up <- 0
data$down <- 0
for (i in ((21*10)+1): nrow(data)) {
sub <- subset(data, data$date[i-(21*10)] < data$date & data$date < data$date[i])
data$up[i] <- mean(sub$ratio) + 2.25*sd(sub$ratio)
data$down[i] <- mean(sub$ratio) - 2.25*sd(sub$ratio)
}
here是样本数据和我的预期输出。谢谢你的帮助!
答案 0 :(得分:0)
*已编辑,因为我最初没有看到所需的结果。
基本上,我使用dplyr使用RcppRoll
创建滚动平均值和sd列。然后,group by
再次进行日期和变异,以便每天只保留最后一个条目。我们必须这样做以确保正确计算sd。
library(RcppRoll); library(dplyr)
data <- data.frame(date=rep(seq.Date(from=as.Date("2017-01-01"),to=as.Date("2017-05-01"),by="days"),each =10),
ratio=1:110,stringsAsFactors=FALSE)
data%>%
mutate(up=roll_meanr(ratio,n=21*10)+2.25*roll_sdr(ratio,n=21*10),
down=roll_meanr(ratio,n=21*10)-2.25*roll_sdr(ratio,n=21*10))%>%
group_by(date)%>%
mutate(up=last(up),down=last(down))
date ratio up down
<date> <int> <dbl> <dbl>
1 2017-04-30 96 121.9414 -15.70329
2 2017-04-30 97 121.9414 -15.70329
3 2017-04-30 98 121.9414 -15.70329
4 2017-04-30 99 121.9414 -15.70329
5 2017-04-30 100 121.9414 -15.70329
6 2017-05-01 101 126.7033 -10.94139
7 2017-05-01 102 126.7033 -10.94139
8 2017-05-01 103 126.7033 -10.94139
9 2017-05-01 104 126.7033 -10.94139
10 2017-05-01 105 126.7033 -10.94139
11 2017-05-01 106 126.7033 -10.94139
12 2017-05-01 107 126.7033 -10.94139
13 2017-05-01 108 126.7033 -10.94139
14 2017-05-01 109 126.7033 -10.94139
15 2017-05-01 110 126.7033 -10.94139
EDIT2 如果您对每天的平均值(而不是所有210个值)计算标准偏差,您可以这样做:
data%>%
group_by(date)%>%
summarise(mean_ratio=mean(ratio))%>%
mutate(up=roll_meanr(mean_ratio,n=21)+2.25*roll_sdr(mean_ratio,n=21),
down=roll_meanr(mean_ratio,n=21)-2.25*roll_sdr(mean_ratio,n=21))%>%
left_join(data,.)
date ratio mean_ratio up down
1196 2017-04-30 96 95.5 123.1605 -16.92239
1197 2017-04-30 97 95.5 123.1605 -16.92239
1198 2017-04-30 98 95.5 123.1605 -16.92239
1199 2017-04-30 99 95.5 123.1605 -16.92239
1200 2017-04-30 100 95.5 123.1605 -16.92239
1201 2017-05-01 101 105.5 127.9224 -12.16049
1202 2017-05-01 102 105.5 127.9224 -12.16049
1203 2017-05-01 103 105.5 127.9224 -12.16049
1204 2017-05-01 104 105.5 127.9224 -12.16049
1205 2017-05-01 105 105.5 127.9224 -12.16049
1206 2017-05-01 106 105.5 127.9224 -12.16049
1207 2017-05-01 107 105.5 127.9224 -12.16049
1208 2017-05-01 108 105.5 127.9224 -12.16049
1209 2017-05-01 109 105.5 127.9224 -12.16049
1210 2017-05-01 110 105.5 127.9224 -12.16049