[英]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 以匹配此結果中最長的列。 后面的組可能有類似的問題,但只報告第一個以保存填充警告緩沖區。
可以愉快地忽略。
發出警告是因為huft
是NA
for 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
現在,每個時間步長只有一行,因為多個因子值已聚合在一個列表元素中。
不完全確定你想做什么,但如果我理解正確的話是這樣的:
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.