簡體   English   中英

R:如何找到重疊數據點且沒有缺失數據的最長周期?

[英]R: How to find longest periods with overlapping data points and no missing data?

我有一個非常大的來自變電站的電力負荷時間序列數據集,該數據集已被清理為具有一致的 15 分鍾時間間隔,但是仍然存在大量缺失數據。 變電站被分成單獨的饋線,因此形式如下:

Feeder <- c("F1","F1","F1","F1","F1", "F2","F2","F2","F2","F2", "F3","F3","F3","F3","F3")
Load <- c(3.1, NA, 4.0, 3.8, 3.6, 2.1, NA, 2.6, 2.9, 3.0, 2.4, NA, 2.3, 2.2, 2.5)

start <- as.POSIXct("2016-01-12 23:15:00")
end <- as.POSIXct("2016-01-13 00:15:00")
DateTimeseq <- seq(start, end, by = "15 min")
DateTime <- c(DateTimeseq, DateTimeseq, DateTimeseq)

dt <- data.frame(Feeder, Load, DateTime)

我的實際數據跨越多年,但我已將其濃縮,因此很容易復制。 如您所見,存在缺失值。 我的實際數據集有大量缺失數據。 為了進行有效的分析,我需要找到所有饋線都沒有丟失負載數據點的時段(即最長的重疊時段)。 如果可能的話,我想生成一個沒有任何 NA 值的最長重疊周期列表,最小值約為 24 小時(我知道這對於我給出的示例來說是不可能的,但如果你能告訴我這將是多么棒。 )。 在此示例中,您可以使用至少 15 分鍾或其他時間。

從簡單的數據可以看出,2016-01-12 23:45:00 到 2016-01-13 00:15:00 之間的最長周期為 30 分鍾。 但是,在此示例中,第二長的時間段將是 15 分鍾,但在最長的時間段內。 如果可能的話,我想運行它,這樣它就不會復制值。 如果是這樣,在這種情況下,第二長的時間段將是 2016-01-12 23:15:00 的重疊點。

隨意玩弄它並添加更多值,如果它會使它更容易的話。 為不同的饋線創建單獨的列可能是有益的。 我通常使用 dplyr 的管道,但這不是必需的。 如果您需要更多信息,請隨時詢問。

謝謝!

也許,這會給你一個開始。 對於每個Feeder ,您可以在NA值之間創建組,計算它們的第一個和最后一個值,並在它們之間創建一個 15 分鍾的序列。 然后,您可以count數據中哪個區間出現的次數最多。

library(dplyr)

dt %>%
  group_by(Feeder) %>%
  group_by(grp = cumsum(is.na(Load)), .add = TRUE) %>%
  #Use add = TRUE in old dplyr
  #group_by(grp = cumsum(is.na(Load)), add = TRUE) %>%
  summarise(start = first(DateTime), 
            end = last(DateTime)) %>%
  ungroup %>%
  mutate(datetime = purrr::map2(start, end, seq, by = '15 mins')) %>%
  tidyr::unnest(datetime) %>%
  select(-start, -end) %>%
  count(datetime, sort = TRUE)

基礎 R 解決方案:

# Strategy 1 contiguous period classification:
data.frame(do.call("rbind", lapply(split(dt, dt$Feeder), function(x){
    y <- with(x, x[order(DateTime),])
    y$category <- paste0(y$Feeder, ":", cumsum(is.na(y$Load)) + 1)
    tmp <- y[!(is.na(y$Load)),]
    cat_diff <- do.call("rbind", lapply(split(tmp, tmp$category), 
                function(z){
                  data.frame(category = unique(z$category), 
                    max_diff = difftime(max(z$DateTime),
                                        min(z$DateTime), 
                                        units = "hours"))}))
    y$max_diff <- cat_diff$max_diff[match(y$category, cat_diff$category)] 
    return(y)
      }
    )
  ), row.names = NULL
)

這是轉換為寬表並檢查沒有任何 NA 的連續行的另一個選項:

library(data.table)

wDT <- dcast(setDT(dt)[, na := +is.na(Load)], DateTime ~ Feeder, value.var="na")

wDT[, c("ri", "rr") := {
    ri <- rleid(rowSums(.SD)==0L)
    .(ri, rowid(ri))
}, .SDcols=names(wDT)[-1L]]
range(wDT[ri %in% ri[rr==max(rr)]]$DateTime)
#[1] "2016-01-12 23:45:00 +08" "2016-01-13 00:15:00 +08"

我可能會為您提供一個不錯的 3 行代碼解決方案:

  1. 首先將數據轉換為寬格式,每個 Feeder 都是一列
  2. 檢查行明智(現在是時間戳明智),所有饋線都是非 NA。 這給出了類似 12:15 TRUE, 12:30 TRUE, 12:45 FALSE,... FALSE 在這種情況下意味着所有饋線都可用於此時間戳
  3. 對生成的 True,True,False,False,... 系列進行運行長度編碼 - 這可以找到您所謂的連續重疊周期

代碼:

 library("tidyr")
 library("dplyr")
 # Into wide format
 dt_wide <- dt %>% pivot_wider(names_from = Feeder, values_from = Load)

 # Check if complete row is available
  dt_anyna <- apply(y,1, anyNA)
 
 # Now we need to find the longest FALSE runs
  rle(dt_anyna)

這為您提供了運行長度編碼,如下所示

  Run Length Encoding
  lengths: int [1:3] 1 1 3
  values : logi [1:3] FALSE TRUE FALSE

意思是一開始你連續有 1 個 False,接下來連續 1 個 TRUE,接下來連續 3 個 FALSE。

您現在可以輕松地處理此結果。 您可能想要過濾掉 TRUE 運行,因為您只尋找最長的運行,其中所有數據都可用(這些是 FALSE 運行)。 然后您可以查找 max() 運行,您還可以查找例如運行 > 4(對於您的 15 分鍾數據而言,這將是 1 小時)。

來自埃利斯的問題的附加代碼

rle <- rle(dt_anyna)
x <- data.frame(  value = rle$values, duration = rle$lengths)
x$start <- dt_wide$DateTime[(cumsum(x$duration)- x$duration)+1]
x$end <-  dt_wide$DateTime[cumsum(x$duration)]
x$duration_s <-  x$end - x$start
ordered <- x[order(x$duration, decreasing = TRUE),]  
filtered <- filter(ordered, value == FALSE)
filtered

因此,只需恢復我們之前結束的位置 - 您可以使用此代碼添加自己的開始/結束時間/持續時間/排序和過濾。 (您現在還必須在開始時調用 library("dplyr"))

結果如下所示:

value  duration   start                end                 duration_s
FALSE        3    2016-01-12 23:45:00 2016-01-13 00:15:00  1800 secs
FALSE        1    2016-01-12 23:15:00 2016-01-12 23:15:00     0 secs

這將為您提供一個按連續非 NA 段的持續時間排序的 data.frame,其中包含開始時間和結束時間。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM