【问题标题】:Subsetting time series data by 3 days and saving in the list将时间序列数据子集 3 天并保存在列表中
【发布时间】:2023-03-25 17:33:01
【问题描述】:

将时间序列设置为 3 天并继续保存在列表中。这样假设第一个子集来自day 1 to day 3,那么第二个子集来自day 2 to day 4,这样每个子集都有3天的数据。请注意,这是 10 分钟的数据时间戳。并根据数据中可用的总天数保存列表中的每个子集。 我试过复制它。

 time_10 <- seq(ISOdatetime(2001,2,1,0,0,0), ISOdatetime(2001,3,31,0,0,0), by=(200))

    a <- as.data.frame(matrix(, nrow = length(time_10), ncol = 4))
    names(a)<- c("time_10","var1","var2","var3")
    a$time_10 <- time_10
    a$var1 <- runif(nrow(a), min=20, max=70)
    a$var2 <- runif(nrow(a), min=10, max=50)
    a$var3 <- runif(nrow(a), min= 3, max=10)
    head(a)  

这是我附上的图像,它将给出子设置时间序列数据并将其保存在列表中的想法。分别为 D1:day1,D2:day2,D3:day3。使用 For 循环或任何其他最佳方法是值得赞赏的。注意:因此,在 For 循环中,3 天的数据子设置将继续发生并保存在索引为 (Subset_n) 的列表中,其中 n 是子集编号。

【问题讨论】:

  • 理论上可以缺少日期吗?
  • 这是10分钟的数据时间戳不,不是发布的数据,间隔是3m20s。
  • @RuiBarradas 间隔可以是任何东西,我们必须从 12Pm 到 12Am 进行子集化。间隔可以随机或固定,但很确定它们不会丢失任何时间戳
  • @RomanLuštrik 抱歉,我没有收到您的问题。但他们肯定不会错过任何日期。
  • 在你的图中,不应该是D1-D2-D3、D2-D3-D4、D3-D4-D5吗?至少我是这样阅读问题开头部分的。

标签: r list for-loop time-series


【解决方案1】:

我相信以下代码可以满足要求。它使用 lubridate 包中的函数 minutes 来简化日期/时间运算。

days3 <- lubridate::days(3)
d1 <- a$time_10[1]
d2 <- a$time_10[nrow(a)] - lubridate::days(2)

res <- lapply(seq(d1, d2, by = "1 days"), function(d){
  i <- which(d <= a$time_10 & a$time_10 < d + days3)
  a[i, ]
})

编辑。
我发现res 的每个数据帧中的行数很麻烦,很难检查上面的代码是否确实产生了预期的结果。这是一种检查方法。

check <- lapply(res, function(DF) lubridate::day(DF$time_10))
check <- sapply(check, function(x) rle(x)$values)
head(check, 3)
#[[1]]
#[1] 1 2 3
#
#[[2]]
#[1] 2 3 4
#
#[[3]]
#[1] 3 4 5

rm(check)    # tidy up

数据。

我将重新发布数据创建代码,因为原始代码不可重现。

set.seed(8893)

time_10 <- seq(ISOdatetime(2001,2,1,0,0,0), ISOdatetime(2001,3,31,0,0,0), by=(200))
var1 <- runif(length(time_10), min=20, max=70)
var2 <- runif(length(time_10), min=50, max=90)
var3 <- runif(length(time_10), min=50, max=90)

a <- data.frame(time_10, var1, var2, var3)

【讨论】:

    【解决方案2】:

    这似乎适用于您的情况。我所做的是提取日期并从头到尾滚动 3 天窗口 (ww)。对于每一步,我都会根据窗口中的天数对一个 data.frame 进行子集化并将其存储到一个列表中。

    time_10 <- seq(ISOdatetime(2001,2,1,0,0,0), ISOdatetime(2001,3,31,0,0,0), by=(200))
    var1 <- runif(length(time_10), min=20, max=70)
    var2 <- runif(length(time_10), min=50, max=90)
    var3 <- runif(length(time_10), min=50, max=90)
    
    a <- as.data.frame(matrix(, nrow = length(time_10), ncol = 4))
    names(a)<- c("time_10","var1","var2","var3")
    a$time_10 <- time_10
    a$var1 <- var1
    a$var2 <- var2
    a$var3 <- var3
    
    date <- strptime(a$time_10, format = "%Y-%m-%d")
    td10 <- sort(unique(date))
    
    ww <- 3
    out <- vector("list", length(td10) - round(ww/2))  # preallocate a list
    
    for (i in 1:length(td10)) {
      bb <- i:(i + ww - 1) # this is the bounding box
    
      if (max(bb) > length(td10)) {
        message("End of time series reached, exiting.")
        return(NULL)
      }
    
      out[[i]] <- a[date %in% td10[bb], ]
    }
    
    # check ranges of dates for each subset
    lapply(out, FUN = function(x) range(x$time_10))
    

    【讨论】:

      猜你喜欢
      • 2016-09-06
      • 2021-05-20
      • 1970-01-01
      • 2012-03-11
      • 2021-07-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多