Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/r/77.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何使用R中的每日数据查找几个月的滚动sd_R_Standard Deviation_Rollapply - Fatal编程技术网

如何使用R中的每日数据查找几个月的滚动sd

如何使用R中的每日数据查找几个月的滚动sd,r,standard-deviation,rollapply,R,Standard Deviation,Rollapply,我对R是相当陌生的,我正在尝试寻找整数组中几个月(3、6、9)内的滚动标准差。例如,对于一年的数据和三组,我想找出(1月、2月、3月)、(2月、3月、4月、3月、3月、3月、3月、3月、3月、3月、3月、3月、3月、3月、3月、3月、3月、3月、3月、3月、3月、3月、3月、3月、3月、3月、 在我的dataframe df中,我有NUM列:和用于查找标准偏差的值,NO列:定义组的整数,以及包含每日日期的date列。我还创建了列Yr_Mo,它是一个整数,对应于日期的年和月。例如,2017年1月的

我对R是相当陌生的,我正在尝试寻找整数组中几个月(3、6、9)内的滚动标准差。例如,对于一年的数据和三组,我想找出(1月、2月、3月)、(2月、3月、4月、3月、3月、3月、3月、3月、3月、3月、3月、3月、3月、3月、3月、3月、3月、3月、3月、3月、3月、3月、3月、3月、3月、3月、

在我的dataframe df中,我有NUM列:和用于查找标准偏差的值,NO列:定义组的整数,以及包含每日日期的date列。我还创建了列Yr_Mo,它是一个整数,对应于日期的年和月。例如,2017年1月的所有日期在Yr_Mo列中的值为1701

一个月来,我使用了聚合:
新使用方差的定义(参见)和OP在问题中提到的内容(即
聚合
滚动应用
),我们可以计算滚动3个月的标准偏差,如下所示。更多评论在线

winsize <- 3

#calculate sum of squares of NUM by month and group
sumxsq <- aggregate(NUM ~ Yr_Mo + NO, df, function(x) sum(x^2))
names(sumxsq) <- c("Yr_Mo", "NO", "SUM_X_SQ")

#calculate sum of NUM by month and group
sumx <- aggregate(NUM ~ Yr_Mo + NO, df, sum)
names(sumx) <- c("Yr_Mo", "NO", "SUM_X")

#count number of observations by month and group
nobs <- aggregate(NUM ~ Yr_Mo + NO, df, length)
names(nobs) <- c("Yr_Mo", "NO", "N")

#merge all stats together
mySD <- merge(merge(sumxsq, sumx, by=c("NO","Yr_Mo")), nobs, by=c("NO","Yr_Mo"))

#calculate rolling sample variance using zoo::rollapplyr by group, then take sqrt for sd
mySD$STD_DEV <- sqrt(unlist(by(mySD, mySD$NO, function(submySD) {
    zoo::rollapplyr(submySD, 
        width=winsize, 
        FUN=function(x) (sum(x[,"SUM_X_SQ"]) - sum(x[,"SUM_X"])^2 / sum(x[,"N"])) / (sum(x[,"N"]) - 1), 
        by.column=FALSE,
        fill=NA)
})))
mySD
winsize您可以创建一个函数来分割数据,使用
Yr\u Mo
列创建子集的上下边界,然后只需获取子集范围的
sd()
值。如果
df
是您上面提供的数据集,请首先重新排列数据集(不需要,但更容易检查输出是否正确)

很抱歉,完全没有注意到您希望保留
分组。这应该可以做到这一点(
df
这里是您上面提供的示例数据):

此函数迭代每个唯一的
Yr_Mo
值,以生成范围的上限和下限(在本例中为x-1:x+1)。然后,它根据这些边界对提供的数据帧进行子集,并计算
NUM
sd
。如果子集无效(时间范围内可用的时间少于三个月),则输出为
NA

roll_sd <- function(df_, lead = 1, lag = -1) {
  id_sd <- do.call(rbind, lapply(unique(df_$Yr_Mo), function(x) {
    start = x + lag
    end = x + lead
    group = df_[df_$Yr_Mo >= start & df_$Yr_Mo <= end,]
    group_sd = sd(group$NUM)
    group_sd = ifelse(length(unique(group$Yr_Mo)) < 3, NA, sd(group$NUM))
    out = data.frame(central_value = x, group_sd)
  })
  )
}

central_值
列是滑动窗口的“中间”月份值groupby
语义应该很简单。嗯,我不明白如何使用非重叠块来获得滚动std开发人员?我已经添加了一个版本的数据,我正在使用的情况下,使我的问题更清楚。
df <- read.csv(text="NO,date,Yr_Mo,NUM
1,2017-01-01,1701,3.4
1,2017-01-02,1701,5
1,2017-01-12,1701,4.2
1,2017-01-13,1701,1
1,2017-01-20,1701,6
1,2017-02-03,1702,3.9
1,2017-02-08,1702,5.5
1,2017-02-15,1702,8
1,2017-02-22,1702,1.1
1,2017-02-26,1702,4
1,2017-03-02,1703,1
1,2017-03-07,1703,7.5
1,2017-03-11,1703,2
1,2017-03-20,1703,3.1
1,2017-03-28,1703,2
1,2017-04-01,1704,2
1,2017-04-05,1704,3.5
1,2017-04-12,1704,1
1,2017-04-19,1704,4.1
1,2017-04-23,1704,5
1,2017-05-02,1705,1
1,2017-05-03,1705,4.5
1,2017-05-04,1705,2
1,2017-05-10,1705,6.1
1,2017-05-20,1705,7
2,2017-01-01,1701,3
2,2017-01-02,1701,53
2,2017-01-11,1701,2
2,2017-01-15,1701,4.1
2,2017-01-22,1701,1
2,2017-02-01,1702,8.9
2,2017-02-08,1702,1.5
2,2017-02-15,1702,3
2,2017-02-27,1702,7.2
2,2017-02-28,1702,4
2,2017-03-02,1703,1
2,2017-03-07,1703,5.2
2,2017-03-11,1703,2
2,2017-03-21,1703,1
2,2017-03-28,1703,2
2,2017-04-01,1704,2.4
2,2017-04-05,1704,3.5
2,2017-04-11,1704,1
2,2017-04-19,1704,4.1
2,2017-04-23,1704,3
2,2017-05-02,1705,1.2
2,2017-05-03,1705,4.5
2,2017-05-04,1705,2
2,2017-05-10,1705,6.1
2,2017-05-21,1705,9", header=TRUE)
roll_sd <- function(df_, lead = 1, lag = -1) {
  id_sd <- do.call(rbind, lapply(unique(df_$Yr_Mo), function(x) {
    start = x + lag
    end = x + lead
    group = df_[df_$Yr_Mo >= start & df_$Yr_Mo <= end,]
    group_sd = sd(group$NUM)
    group_sd = ifelse(length(unique(group$Yr_Mo)) < 3, NA, sd(group$NUM))
    out = data.frame(central_value = x, group_sd)
  })
  )
}
library(dplyr)

df2 <- df %>% 
  group_by(NO) %>%
  do(roll_sd(data.frame(.)))

> as.data.frame(df2)
   NO central_value  group_sd
1   1          1701        NA
2   1          1702  2.248449
3   1          1703  2.209460
4   1          1704  2.179406
5   1          1705        NA
6   2          1701        NA
7   2          1702 13.046809
8   2          1703  2.311833
9   2          1704  2.270305
10  2          1705        NA