R语言 在较小的表中使用开始值和结束值来填充较大表中的空列

i86rm4rw  于 2023-05-20  发布在  其他
关注(0)|答案(1)|浏览(131)

我有一百多万行的时间序列,有许多不同的ID,每个ID有数万个数据点。

timeseries <- tibble(ID = c(101, 101, 101, 101, 101), 
                     time = c(1,2,3,4,5), 
                     block = c(0,0,0,0,0))

我还有一个包含数千行的tibble,其中包含事件的开始和结束时间,每个ID都不同,应该在时间序列上标记这些时间(以便可以使用summarize()轻松总结它们)。在事件之间以及每个ID的时间序列的开始和开始处存在空时间点。

blocks <- tibble(ID = c(101, 101), 
                 block = c(1, 2), 
                 st = c(1, 4), 
                 end = c(2,5))

如何做到这一点最容易和快速?
我目前的解决方案非常缓慢和笨拙:

j <- 1
  for(i in 1:nrow(blocks)){
    checkrow <- blocks[i,]
    while(timeseries[j, "ID"] < checkrow["ID"]) j = j+1   # skip wrong ID
    while(timeseries[j, "time"] < checkrow["st"]) j = j+1 # skip timepoints until start
    while(timeseries[j, "time"] < checkrow["end"]){
      timeseries[j, "block"] <- checkrow["block"]         # mark timepoints until end
      j = j+1
    }
    next  # move to next block
  }

我没有时间序列中的开始点和结束点,中间有NA,也不知道如何做到这一点,所以thisthis解决方案没有帮助。
我想留在tidyverse和向量逻辑,而不是循环,但不知道如何。我看了map(),但不知道如何做到这一点。我肯定我错过了一些简单的答案。

u3r8eeie

u3r8eeie1#

我不太确定我是否理解你想达到的目的。这个有用吗

library(powerjoin)
library(dplyr)
timeseries |> 
  select(-block) |> 
  left_join(blocks |> select(-end), by = c("ID", "time" = "st")) |> 
  power_left_join(blocks |> select(-st), by = c("ID", "time" = "end"), conflict = coalesce_xy)

# A tibble: 5 × 3
     ID  time block
  <dbl> <dbl> <dbl>
1   101     1     1
2   101     2     1
3   101     3    NA
4   101     4     2
5   101     5     2

相关问题