簡體   English   中英

將帶有因子的數據表的不規則時間序列轉換為 R 中的規則時間序列

[英]convert a irregular time series of a data table with factors into a regular time series in R

我正在嘗試將數據表的不規則時間序列轉換為規則時間序列。 我的數據看起來像這樣

library(data.table)
dtRes <- data.table(time  = c(0.1, 0.8, 1, 2.3, 2.4, 4.8, 4.9),
                    abst  = c(1, 1, 1, 0, 0, 3, 3),
                    farbe = as.factor(c("keine", "keine", "keine", "keine", "keine", "rot", "blau")),
                    gier  = c(2.5, 2.5, 2.5, 0, 0, 3, 3),
                    goff  = as.factor(c("haus", "maus", "toll", "maus", NA, "maus", "maus")),
                    huft  = as.factor(c(NA, NA, NA, "wolle", "wolle", "holz", "holz")),
                    mode  = c(4, 4, 4, 2.5, NA, 3, 3))

如何通過大約 1 秒的塊大小將觀察結果聚合成塊? (行數可變 - 如果 1 秒內沒有行,則為 0)結果應該是數字列的平均值(省略 NA),如果有超過 1 個唯一行,則結果應該是整個重復行的因子價值。 如果這對於因子是不可能的或者對您沒有意義,那么只取因子列中特定第二個的第一個值也是可以的。 這樣,它將是真正的常規時間序列,沒有任何重復的時間。 如果間隔沒有值(例如第二秒的示例),則結果為 NA。

最后結果可能如下所示(取決於是否重復行):

有重復:

wiDups <- data.table(time  = c(1, 1, 2, 3, 4, 5, 5),
                     abst  = c(1, 1, NA, 1, NA, 5, 5),
                     farbe = as.factor(c("keine", "keine", NA, "keine", NA, "rot", "blau")),
                     gier  = c(2.5, 2.5, NA, 0, NA, 4.5, 4.5),
                     goff  = as.factor(c("haus", "maus", NA, "maus", NA, "maus", "maus")),
                     huft  = as.factor(c(NA, NA, NA, "wolle", NA, "holz", "holz")),
                     mode  = c(5, 5, NA, 2.5, NA, 4, 4))

並且沒有重復:

noDups <- data.table(time  = c(1, 2, 3, 4, 5),
                     abst  = c(1, NA, 1, NA, 5),
                     farbe = as.factor(c("keine", NA, "keine", NA, "rot")),
                     gier  = c(2.5, NA, 0, NA, 4.5),
                     goff  = as.factor(c("haus", NA, "maus", NA, "maus")),
                     huft  = as.factor(c(NA, NA, "wolle", NA, "holz")),
                     mode  = c(5, NA, 2.5, NA, 4))

將其轉換為時間序列object會更好嗎?

這是data.table答案:

time四舍五入到最接近的秒數:

> dtRes[, 
+       lapply(.SD, function(z) {return(ifelse(is.factor(z), levels(z)[unique(z)[1]], mean(z, na.rm = T)))} ), 
+       by = .(time = round(time, digits = 0))]
   time abst farbe gier goff  huft mode
1:    0    1 keine  2.5 haus  <NA>  4.0
2:    1    1 keine  2.5 maus  <NA>  4.0
3:    2    0 keine  0.0 maus wolle  2.5
4:    5    3   rot  3.0 maus  holz  3.0

使用ceiling function:

> dtRes[, 
+       lapply(.SD, function(z) {return(ifelse(is.factor(z), levels(z)[unique(z)[1]], mean(z, na.rm = T)))} ), 
+       by = .(time = ceiling(time))]
   time abst farbe gier goff  huft mode
1:    1    1 keine  2.5 haus  <NA>  4.0
2:    3    0 keine  0.0 maus wolle  2.5
3:    5    3   rot  3.0 maus  holz  3.0

您可以根據需要調整返回level的邏輯。 在這里,我返回與第一個非唯一值對應的level

您可以切換到在ifelse語句中使用as.numeric - 結果相似。 我意識到factor列的數據類型更改為character - 如果您需要factor ,那么您可以在單獨的語句中專門設置它或使用鏈接。

dtRes[, lapply(.SD, ....), by = .(....)][, lapply(.SD, as.factor(...)), .SDcols = .( columns you want as factors), ]

該問題是 OP 問題R 的后續問題,將時間序列中的重復行與數據表中的不同列類型結合起來

OP 已要求通過聚合將不規則時間序列轉換為規則時間序列。

這可以通過右連接聚合和填充缺失值來實現。

win <- 1   # step size of time series or length of time window
brk <- dtRes[, .(time = tail(scales::fullseq(range(time), win), -1L))]
dtRes[, lapply(.SD, function(x) if (is.numeric(x)) mean(x, na.rm = TRUE) 
               else unlist(na.omit(unique(x)))), 
      by = .(time = ceiling(time / win) * win)][
        brk, on = .(time)]
 time abst farbe gier goff huft mode 1: 1 1 keine 2.5 haus <NA> 4.0 2: 1 1 keine 2.5 maus <NA> 4.0 3: 1 1 keine 2.5 toll <NA> 4.0 4: 2 NA <NA> NA <NA> <NA> NA 5: 3 0 keine 0.0 maus wolle 2.5 6: 4 NA <NA> NA <NA> <NA> NA 7: 5 3 rot 3.0 maus holz 3.0 8: 5 3 blau 3.0 maus holz 3.0

為了創建常規時間序列,為了方便起見,使用來自scales package 的fullseq() 顯然,OP 更喜歡右閉區間,因此可以跳過第一個值。

警告信息

`[.data.table`(dtRes, , lapply(.SD, function(x) if (is.numeric(x)) mean(x,
j 的第 1 組結果的第 5 項長度為零。 這將填充 3 個 NA 以匹配此結果中最長的列。 后面的組可能有類似的問題,但只報告第一個以保存填充警告緩沖區。

可以愉快地忽略。

發出警告是因為huftNA for time == 1 調用na.omit()后, huft列的結果向量為空,但組結果有 3 行。 因此, data.tableNA填充結果向量以獲得匹配長度——這是我們所期望的。


該解決方案被參數化以使用不同的塊大小win 例如,對於win <- 0.5的塊大小,我們得到

 time abst farbe gier goff huft mode 1: 0.5 1 keine 2.5 haus <NA> 4.0 2: 1.0 1 keine 2.5 maus <NA> 4.0 3: 1.0 1 keine 2.5 toll <NA> 4.0 4: 1.5 NA <NA> NA <NA> <NA> NA 5: 2.0 NA <NA> NA <NA> <NA> NA 6: 2.5 0 keine 0.0 maus wolle 2.5 7: 3.0 NA <NA> NA <NA> <NA> NA 8: 3.5 NA <NA> NA <NA> <NA> NA 9: 4.0 NA <NA> NA <NA> <NA> NA 10: 4.5 NA <NA> NA <NA> <NA> NA 11: 5.0 3 rot 3.0 maus holz 3.0 12: 5.0 3 blau 3.0 maus holz 3.0

有更多的行要填寫。

對於win <- 2的塊大小,我們得到

 time abst farbe gier goff huft mode 1: 2 1 keine 2.5 haus <NA> 4.0 2: 2 1 keine 2.5 maus <NA> 4.0 3: 2 1 keine 2.5 toll <NA> 4.0 4: 4 0 keine 0.0 maus wolle 2.5 5: 6 3 rot 3.0 maus holz 3.0 6: 6 3 blau 3.0 maus holz 3.0

每個時間間隔具有多行的時間序列不是常規時間序列,恕我直言。 稍加修改,我們可以得到

win <- 1
brk <- dtRes[, .(time = scales::fullseq(range(time), win)[-1L])]
dtRes[, lapply(.SD, function(x) if (is.numeric(x)) mean(x, na.rm = TRUE) 
               else list(na.omit(unique(x)))), 
      by = .(time = ceiling(time / win) * win)][
        brk, on = .(time)]
 time abst farbe gier goff huft mode 1: 1 1 keine 2.5 haus,maus,toll 4.0 2: 2 NA NA NA 3: 3 0 keine 0.0 maus wolle 2.5 4: 4 NA NA NA 5: 5 3 rot,blau 3.0 maus holz 3.0

現在,每個時間步長只有一行,因為多個因子值已聚合在一個列表元素中。

不完全確定你想做什么,但如果我理解正確的話是這樣的:

dtRes %>% 
  group_by(second = ceiling(time)) %>% 
  summarise(abst = mean(abst),
            farbe = farbe[1],
            gier = mean(gier),
            goff = goff[1],
            huft = huft[1],
            mode = mean(mode)) %>% 
  add_row(second = c(1:10)[!(c(1:10) %in% .$second)]) %>% #change 10 to however many seconds you will have
  arrange(second)

# A tibble: 10 x 7
   second  abst farbe  gier goff  huft   mode
    <dbl> <dbl> <fct> <dbl> <fct> <fct> <dbl>
 1      1     1 keine   2.5 haus  NA        4
 2      2    NA NA     NA   NA    NA       NA
 3      3     0 keine   0   maus  wolle    NA
 4      4    NA NA     NA   NA    NA       NA
 5      5     3 rot     3   maus  holz      3
 6      6    NA NA     NA   NA    NA       NA
 7      7    NA NA     NA   NA    NA       NA
 8      8    NA NA     NA   NA    NA       NA
 9      9    NA NA     NA   NA    NA       NA
10     10    NA NA     NA   NA    NA       NA

請注意,從您的示例中不清楚您如何將時間四舍五入到秒,但我認為您總是想四舍五入?

暫無
暫無

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

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