【问题标题】:Optimizing timeseries manipulation without loops: is it possible?优化没有循环的时间序列操作:有可能吗?
【发布时间】:2021-10-25 19:11:18
【问题描述】:

问题很简单:单变量数据的时间聚合。一个通用的例子:

x <- seq(from=as.Date('2000-01-01'),by='1 day',length.out=10^6)
y <- runif(10^6)
xy <- data.frame(x=x,y=y)

x.mean <- seq(from=as.Date('2000-01-15'),by='1 month',length.out=30000)
y.mean <- rep(NA,30000)
xy.mean <- data.frame(x=x.mean,y=y.mean)

for(i in 1:29999)
{
  read.mean <- xy.mean[i,1] <= xy[,1] & xy[,1] < xy.mean[i+1,1]
  xy.mean[i,2] <- mean(xy[read.mean,2])
}

我可以用几分钟、几年、几周或几十年来代替几天和几个月。我的代码可以工作,但是太慢了。我怎样才能加快这个过程?我知道 xy.mean[,1],我需要计算 xy.mean[,2]。

如果您建议使用包,我想了解包如何加快进程。

非常感谢!

【问题讨论】:

    标签: r time-series


    【解决方案1】:

    在某个地方总是需要一个循环来处理这些问题。诀窍是不要在 R 中而是在像 C 这样更快、更低级别的语言中执行循环。我相信这也是许多包提高速度的方式。

    在这种情况下,您也可以不使用额外的软件包:

    1. 使用函数findIntervalxy 的所有行分配一个“组索引”。因此,如果xy$x 小于xy.mean$x,它的索引为0,如果它在xy.mean$x 的第一行和第二行之间,它的索引为1,依此类推。

    2. 使用tapply 计算每组的平均值。

       x <- seq(from=as.Date('2000-01-01'),by='1 day',length.out=10^6)
       y <- runif(10^6)
       xy <- data.frame(x=x,y=y)
      
      
       x.mean <- seq(from=as.Date('2000-01-15'),by='1 month',length.out=30000)
      
       group <- findInterval(xy$x, x.mean)
      
       y.mean <- tapply(xy$y, group, mean)
      
       ## I'm not sure if you'd like to delete the first or the last group
       ## I believe the old code deleted the last group, so I did it this way
       xy.mean <- data.frame(x=x.mean,y=y.mean[-length(y.mean)]) 
      

    【讨论】:

    • 你的答案是完美的。非常感谢,我不知道findInterval函数。
    猜你喜欢
    • 2015-08-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-24
    • 2020-10-22
    相关资源
    最近更新 更多