У меня есть список рекурсивных списков, которые я хотел бы объединить в один data.table
. Каждый элемент списка верхнего уровня (mylist
) имеет два элемента:
Timestamp
, который представляет собой вектор символов Value
, который представляет собой список
Несмотря на структуру (изображение ниже), каждый элемент имеет класс data.table
.
На рисунке ниже показана структура этого списка (код был бы слишком длинным):
> str(mylist[[1]])
Classes ‘data.table’ and 'data.frame': 10 obs. of 2 variables:
$ Timestamp: chr "2019-06-01T00:00:00Z" "2019-06-01T00:15:00Z" "2019-06-01T00:30:00Z" "2019-06-01T00:45:00Z" ...
$ Value :List of 10
..$ : num 100
..$ : num 100
..$ : num 100
..$ : num 100
..$ : num 100
..$ : num 100
..$ : num 100
..$ : num 100
..$ : num 100
..$ : num 100
Right теперь я запускаю два цикла, чтобы получить объединенное data.table
:
L oop 1 для преобразования Timestamp
в R дату и время и установить key
new_list <- lapply(1:length(mylist), function(n){
z <- mylist[[n]]
c1 <- as.POSIXct(z$Timestamp, format = '%Y-%m-%dT%H:%M:%S', tz = 'UTC')
c2 <- as.numeric(unlist(z$Value))
dt <- data.table(c1 = c1, c2 = c2)
colnames(dt) <- c('time', names(mylist)[n])
setkey(dt, 'time')
return((dt))
})
key
настроен для быстрого слияния (открыт для других более быстрых способов). Это l oop завершается ошибкой, когда он встречает пустой data.table
(4-й элемент в этом списке).
L oop 2, чтобы объединить список в один data.table
Очевидно, что это работает только тогда, когда L oop 1 не дает сбой, т.е. нет нуля data.table
в списке.
dt <- new_list [<a href="https://i.stack.imgur.com/nqJYq.png" rel="nofollow noreferrer"> 1 ] lapply (2: length (new_list), function (k) {dt << - объединить (dt, new_list [[k]) ], by = 'time', all = T)}) </p>
Итак, мои проблемы:
- Что делать, если одна из записей в
mylist
пуста data.table
или list
. - Каков наилучший способ объединить их всех с точки зрения скорости и возможных ошибок.
Пример данных приведен ниже, мой фактический список содержит 40 записей, каждая из которых ~ 30 000 строк.
Обновление: Комбинированный L oop
listMerge <- function(listname){
ret_list <- lapply(1:length(listname), function(n){
z <- listname[[n]]
c1 <- as.POSIXct(z$Timestamp, format = '%Y-%m-%dT%H:%M:%S', tz = 'UTC')
c2 <- as.numeric(unlist(z$Value))
dt <- data.table(c1 = c1, c2 = c2)
colnames(dt) <- c('time', names(listname)[n])
setkey(dt, 'time')
return((dt))
})
ndat <- ret_list[[1]]
lapply(2:length(ret_list), function(k){
if(nrow(ret_list[[k]]) > 0){
ndat <<- merge(ndat, h[[k]], by = 'time', all = T)
}
})
return(ndat)
}
Это работает - не уверен, что есть более быстрый способ получить желаемый стол.
Данные
dput(mylist)
list(A = structure(list(Timestamp = c("2019-06-01T00:00:00Z",
"2019-06-01T00:15:00Z", "2019-06-01T00:30:00Z", "2019-06-01T00:45:00Z",
"2019-06-01T01:00:00Z", "2019-06-01T01:15:00Z", "2019-06-01T01:30:00Z",
"2019-06-01T01:45:00Z", "2019-06-01T02:00:00Z", "2019-06-01T02:15:00Z"
), Value = list(100.050957, 100.080826, 100.120308, 100.053459,
100.053825, 100.04792, 100.0679, 100.088554, 100.102737,
100.103653)), row.names = c(NA, -10L), class = c("data.table",
"data.frame"), .internal.selfref = <pointer: 0x7fe0a100a6e0>),
B = structure(list(Timestamp = c("2019-06-01T00:00:00Z",
"2019-06-01T00:15:00Z", "2019-06-01T00:30:00Z", "2019-06-01T00:45:00Z",
"2019-06-01T01:00:00Z", "2019-06-01T01:15:00Z", "2019-06-01T01:30:00Z",
"2019-06-01T01:45:00Z", "2019-06-01T02:00:00Z", "2019-06-01T02:15:00Z"
), Value = list(38.892395, 45.7738266, 53.21701, 57.08103,
62.1048546, 68.58914, 68.98703, 69.5170746, 71.49378,
78.59612)), row.names = c(NA, -10L), class = c("data.table",
"data.frame"), .internal.selfref = <pointer: 0x7fe0a100a6e0>),
C = structure(list(Timestamp = c("2019-06-01T00:00:00Z",
"2019-06-01T00:15:00Z", "2019-06-01T00:30:00Z", "2019-06-01T00:45:00Z",
"2019-06-01T01:00:00Z", "2019-06-01T01:15:00Z", "2019-06-01T01:30:00Z",
"2019-06-01T01:45:00Z", "2019-06-01T02:00:00Z", "2019-06-01T02:15:00Z"
), Value = list(30.5898361, 29.75237, 27.63596, 26.5089836,
25.6826324, 24.909977, 24.4333439, 23.5524445, 23.1864853,
22.7402916)), row.names = c(NA, -10L), class = c("data.table",
"data.frame"), .internal.selfref = <pointer: 0x7fe0a100a6e0>),
D = NULL, E = structure(list(Timestamp = c("2019-06-01T00:00:00Z",
"2019-06-01T00:15:00Z", "2019-06-01T00:30:00Z", "2019-06-01T00:45:00Z",
"2019-06-01T01:00:00Z", "2019-06-01T01:15:00Z", "2019-06-01T01:30:00Z",
"2019-06-01T01:45:00Z", "2019-06-01T02:00:00Z", "2019-06-01T02:15:00Z"
), Value = list(8.299942, 8.44268, 8.440144, 8.445086, 8.41551,
8.424382, 8.438655, 8.46398, 8.445853, 8.476906)), row.names = c(NA,
-10L), class = c("data.table", "data.frame"), .internal.selfref = <pointer: 0x7fe0a100a6e0>),
F = structure(list(Timestamp = c("2019-06-01T00:00:00Z",
"2019-06-01T00:15:00Z", "2019-06-01T00:30:00Z", "2019-06-01T00:45:00Z",
"2019-06-01T01:00:00Z", "2019-06-01T01:15:00Z", "2019-06-01T01:30:00Z",
"2019-06-01T01:45:00Z", "2019-06-01T02:00:00Z", "2019-06-01T02:15:00Z"
), Value = list(85.48002, 88.071, 87.71461, 86.2900848, 85.50101,
82.4923248, 81.78603, 82.4504547, 82.00605, 82.12493)), row.names = c(NA,
-10L), class = c("data.table", "data.frame"), .internal.selfref = <pointer: 0x7fe0a100a6e0>),
G = structure(list(Timestamp = c("2019-06-01T00:00:00Z",
"2019-06-01T00:15:00Z", "2019-06-01T00:30:00Z", "2019-06-01T00:45:00Z",
"2019-06-01T01:00:00Z", "2019-06-01T01:15:00Z", "2019-06-01T01:30:00Z",
"2019-06-01T01:45:00Z", "2019-06-01T02:00:00Z", "2019-06-01T02:15:00Z"
), Value = list(0.870313, 0.862552762, 0.8827777, 0.8639478,
0.849139452, 0.874981, 0.833493, 0.89307636, 0.8647241,
0.8711139)), row.names = c(NA, -10L), class = c("data.table",
"data.frame"), .internal.selfref = <pointer: 0x7fe0a100a6e0>))