首页 > 解决方案 > 使用过去的迭代矢量化移动窗口

问题描述

给定一个非常大的数据集(> 100 万次观察),并且正在尝试对我的逻辑进行矢量化,但还没有找到解决它的 R 化方法。

问题是每次我在变量中有“坏”观察时,我都需要检查前 5 次观察是否有“好”指标。只要前面有 5 个“好”观察,就会保留“坏”观察。如果在 5 个观察移动窗口内有“坏”的观察,那么该观察最终将从分析中删除。

到目前为止,我已经尝试使用带有ifelse()逻辑的 for 循环。逻辑检查出来了,但是使用 R 的处理需要几个小时才能完成。我已经查看了zoo滚动窗口的包,但没有应用聚合函数,如mean()or sum()。我也研究过apply(),lapply()等,但无法使它们工作。

这是我的 for 循环代码。让df$Observation成为好与坏的初始名称,让df$Result成为我们是否保留或放弃观察的决定。

编辑

set.seed(1)
df <- data.frame(Observation = sample(c("Good", "Bad"), 1000, T, c(0.9,0.1)))

for(i in 1:nrow(df)){
  ifelse(
    df$Observation[i] == "Good",
    df$Result[i] <- "Keep",
    ifelse(
      df$Observation[i] == "Bad" &
        df$Observation[i-1] == "Good" &
        df$Observation[i-2] == "Good" &
        df$Observation[i-3] == "Good" &
        df$Observation[i-4] == "Good",
      df$Result[i] <- "Keep",
      df$Result[i] <- "Drop"
    )
  )
}

示例期望结果:

df[385:393,]

    Observation Result
385        Good   Keep
386        Good   Keep
387        Good   Keep
388        Good   Keep
389        Good   Keep
390         Bad   Keep
391        Good   Keep
392        Good   Keep
393         Bad   Drop

代码按预期工作,但我需要一种更有效的方式在 R 中执行它。感谢您的帮助!

标签: rloopsvectorization

解决方案


我喜欢zoo这个。除了第一个 bad 实例(之前只有 3 个 obs)之外,这一切似乎都匹配。您可以调整逻辑以保持该逻辑使用fill = 4

library(tidyverse)
library(zoo)

df_decision <-
  df %>% 
  mutate(
    good_ind = as.integer(Observation == "Good"),
    good_count = rollsum(good_ind, 5, align = "right", fill = good_ind),
    result =ifelse(good_ind == 1 | good_count >= 4, "keep", "drop")
  )

推荐阅读