【问题标题】:Find the longest, Non-NA common sequence between two time series in R在R中找到两个时间序列之间最长的非NA公共序列
【发布时间】:2021-03-08 20:08:26
【问题描述】:

假设我有两个不同长度的时间序列。两者都有timevalue 列。它们都在随机位置具有 NA 值。例如:

# Generate first series
series1 <- data.frame(
    time = seq.POSIXt(
        from = as.POSIXct("2020-01-01", origin = "1970-01-01"),
        length.out = 100,
        by = "1 day"
    ),
    value = runif(100, min = 0, max = 100)
)

# Generate second series, which starts and ends and different times
series2 <- data.frame(
    time = seq.POSIXt(
        from = as.POSIXct("2019-12-01", origin = "1970-01-01"),
        length.out = 80,
        by = "1 day"
    ),
    value = runif(80, min = 0, max = 100)
)

# Remove some values at random
random_idx1 <- sample(seq_len(nrow(series1)), 20)
random_idx2 <- sample(seq_len(nrow(series2)), 20)

series1$value[random_idx1] <- NA
series2$value[random_idx2] <- NA

太好了。如果我要确定每个系列的最大非 NA 序列,我可以使用stats::na.contiguous()。但是,一个系列的最长序列与另一个系列不同。

现在的问题是:如何确定两个系列之间最长的重叠非NA值序列?也就是说,两个时间序列之间时间匹配且不是 NA 值的最长值序列是什么?

【问题讨论】:

  • 也许你想在“时间”之前加入他们merge(series1, series2, by = 'time', all = TRUE)
  • 对,那么可以在合并帧上使用 na.contiguous 吗?
  • 我正在尝试您的示例,但我没有找到两者共同的案例,即full_join(series1, series2, by = 'time') %&gt;% summarise(len1 = list(rle(!is.na(value.x) &amp; !is.na(value.y))))。可能是因为您构建的示例不重叠
  • @akrun 我更新了示例。

标签: r dplyr data-science


【解决方案1】:

在问题中,series2 于 2019 年结束,而 series1 于 2020 年开始,因此没有共同运行的非 NA 值,因此让我们使用末尾注释中给出的不同示例。

1) 仅使用基数 R 我们可以做到这一点:

na.contiguous(merge(DF1, DF2, by = 1))

2) 或者我们可以转换为 zoo 并做同样的事情。使用 fortify.zoo(z) 转换回来或将其保留为动物园。如果您想要单独的动物园对象,请使用 z$z1 和 z$z2。请注意,time(z) 是结果中的时间。如果时间间隔有规律,也可以使用 ts 类:as.ts(z)。

library(zoo)
z1 <- read.zoo(DF1)
z2 <- read.zoo(DF2)

z <- na.contiguous(cbind(z1, z2))
z
##   z1 z2
## 3  3 12
## 4  4 13
## 5  5 14
## attr(,"na.action")
## [1] 1 2 6 7
## attr(,"class")
## [1] omit

注意

DF1 <- data.frame(1:6, c(1, 2, 3, 4, 5, NA))
DF2 <- data.frame(2:7, c(NA, 12, 13, 14, 15, 16))

【讨论】:

    【解决方案2】:

    我们通过'time'执行full_join,在逻辑向量(即'value.x'和'value.y'的非NA元素)上应用run-length-id (rle),提取@ 987654323@ 其中“值”为 TRUE,获取 max

    library(dplyr)
    full_join(series1, series2, by = 'time') %>% 
         summarise(len1 = with(rle(!is.na(value.x) &
               !is.na(value.y)), max(lengths[values])))
    # len1
    #1    5
    

    它返回 'series1' 和 'series2' 数据集中的 'value' 列共有的最大非 NA 元素

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-08-26
      • 1970-01-01
      • 2012-02-19
      • 1970-01-01
      • 1970-01-01
      • 2011-05-06
      • 1970-01-01
      • 2011-08-10
      相关资源
      最近更新 更多