首页 > 解决方案 > 将带有因子的数据表的不规则时间序列转换为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))

将其转换为时间序列对象会更好吗?

标签: rdatatabletime-seriesxtszoo

解决方案


该问题是 OP 问题 R 的后续问题,将时间序列中的重复行与 datatable 中的不同列类型结合起来

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

为了创建常规时间序列,使用fullseq()fromscales包是为了方便。显然,OP 更喜欢右闭区间,因此可以跳过第一个值。

警告信息

In `[.data.table`(dtRes, , lapply(.SD, function(x) if (is.numeric(x)) mean(x,
第 1 组 j 的结果的第 5 项长度为零。这将填充 3 个 NA 以匹配此结果中最长的列。后面的组可能有类似的问题,但只报告第一个以保存填充警告缓冲区。

可以愉快地忽略。

发出警告是因为huftNAfor time == 1。调用列na.omit()的结果向量后为huft空,但组结果有 3 行。因此,data.table用 填充结果向量NA以获得匹配的长度——这是我们所期望的。


该解决方案被参数化以使用不同的块大小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

现在,每个时间步长只有一行,因为多个因子值已聚合在一个列表元素中。


推荐阅读