因此,我有一些应该是每天的时间序列数据,但通常会遇到长度不等的中断。例如,在理想情况下,数据看起来像这样(及时转发):
1、1、3、2、4、1、1、5、6、5、6-(1)
但是反而像这样出来:
NA,NA,5,2,4,NA,2,NA,NA,NA,22 ---(2)
我将从这些数据中采样以进行蒙特卡洛模拟,但是如果我只是忽略了NA或将标准差设置为0,则NA字符串后接大量数字显然会歪曲数据的均值。
我要做的是根据NA的长度将数据均匀分布在整个NA字符串中。
例如在(2)中,一个均匀分布的版本看起来像这样:
1.67,1.67,1.67,2,4,1,1,5.5,5.5,5.5,5.5
或更明确地说:
5 / 3、5 / 3、5 / 3、2、4、2 / 2、2 / 2、22 / 4、22 / 4、22 / 4、22 / 4
因此,NA的最终值实际上是(NA字符串后的值)/(+ 1中存在的NA连续天数的长度)
以前,我使用了一个for循环,该循环每天都在时间序列中运行,然后当遇到NA时,不断计数直到达到非NA值,然后取该非NA值并将其除以按counter + 1,然后用另一个for循环将该值替换为先前的NA,这显然很慢。
此外,数据存在于按2个分组ID分组的数据帧中,其中包含两个分组ID的每个唯一组合的时间序列,因此,在此之前,我先将其子集设置为一次获得一个时间序列。如果没有此步骤代码可以更快地运行,那么我可以删除它。
R中的代码如下所示:
newtest是主要数据帧,而eventest是输出。 X,Y,Z是要均匀分布的值变量。 我也将傍晚的时间限制为4天,但不要介意它是否一直持续到一整天。 我知道将行绑定到不断增长的数据帧是很糟糕的做法,并且我正在尝试将插入方法插入到与newtest大小相同但充满了NA的starteventest中。 但是,我认为主要的瓶颈实际上是for循环,这就是为什么我问是否有更好的方法可以做到这一点。
事件<-newtest [0,]
计数<-0
for(i in unique(newtest $ group_id1)){
newtest0 <-子集(newtest,group_id1 == i)
for(j in unique(newtest0 $ Color)){
count <- count + 1
if(count%%200 == 0){print(count)}
newtest1 <- subset(newtest0, group_id2 == j)
counter <- 0
for (n in 1:nrow(newtest1)){
if(is.na(newtest1$Level_Delta[n])){
counter <- counter + 1
ErrorReport <- rbind(ErrorReport, c(i, j, "Missing Intermediate Date", as.character(newtest1$Date[n])))
} else if (counter >= 1 & counter <= 4){
finalx <- newtest1$X[n]
finaly <- newtest1$Y[n]
finalz <- newtest1$Z[n]
for(m in 0:counter){
newtest1$X[n-m] <- finalx/(counter+1)
newtest1$Y[n-m] <- finaly/(counter+1)
newtest1$Z[n-m] <- finalz/(counter+1)
}
counter <- 0
} else {counter <- 0}
}
eventest <- rbind(eventest, newtest1)}}
此代码进行的试用版新测试大约需要2个小时才能完成。但是,最后一天的新测试将大50倍左右,这就是为什么我遇到运行时问题。它可以工作,但是花费的时间太长。
newtest也驻留在SQL Server数据库上(已使用odbc读入R),因此,如果可以通过某种方式在SQL Server上使用查询也可以做到这一点,那就太好了。
任何帮助将不胜感激。谢谢!