在R中,我如何矢量化移动的数据子集?

时间:2017-06-19 18:56:36

标签: r

我在下面有一个循环,它将两个新列分配给数据表,使用最近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是样本数据和我的预期输出。谢谢你的帮助!

1 个答案:

答案 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