Преобразование набора данных временных рядов с несколькими столбцами дат во временные ряды с уникальным столбцом дат или в объект зоопарка

У меня есть большой набор данных, состоящий из нескольких нерегулярных временных рядов с определенным столбцом даты для каждого ряда. Я хочу преобразовать этот набор данных в фрейм данных с уникальным столбцом даты или в объект зоопарка.

Я пробовал read_xls(), read.zoo(). Я попытался изменить форму с помощью pivot_longer(). Я искал в Интернете, но пока не нашел решения.

date1 Var1 date2 Var2 date3 Var3
2023-01-13 100.1 2023-01-11 99.7 2022-11-24 102.3
2023-01-16 104.5 2023-01-12 NA 2022-11-25 99.9
2023-01-17 101.6 2023-01-13 99.9 2022-11-28 99.3
2023-01-18 101.8 2023-01-16 99.1 2022-11-29 NA
2023-01-19 NA 2023-01-17 99.5 2022-11-30 NA

Скажите, как должен выглядеть конечный результат?

AntonySamuelB 12.04.2023 13:07

Каким должно быть окончательное значение даты «2023-01-13», поскольку она имеет 2 значения: 100,1 и 99,9?

NicChr 12.04.2023 13:29

На дату «2023-01-13» Var1 имеет значение 100,1, Var2 — 99,9, а Var3 — нет данных.

Bertrand G 13.04.2023 11:31
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
3
60
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Я дам этот ответ, пока кто-нибудь не придумает что-то более элегантное.

library(tidyverse)
dat <- structure(list(date1 = structure(c(19370, 19373, 19374, 19375, 
                                          19376), class = "Date"), Var1 = c(100.1, 104.5, 101.6, 101.8, 
                                                                            NA), date2 = structure(c(19368, 19369, 19370, 19373, 19374
                                                                            ), class = "Date"), Var2 = c(99.7, 99.8, 99.9, NA, NA), date3 = structure(c(19320, 
                                                                                                                                                            19321, 19324, 19325, 19326), class = "Date"), Var3 = c(102.3, 
                                                                                                                                                                                                                   99.9, 99.3, 100.5, 100.1)), row.names = c(NA, -5L), class = c("tbl_df", 
                                                                                                                                                                                                                                                                                 "tbl", "data.frame"))
dat2 <- dat %>%
  pivot_longer(cols = contains("date"),
               names_to = "date") %>%
  select(date, value, contains("Var")) %>%
  arrange(date) %>%
  mutate(id = group_indices(group_by(., date))) %>%
  select(contains("Var"), date = value, id)

var_nms <- names(select(dat2, contains("Var"))) 
for (i in seq_along(var_nms)){
  dat2[[var_nms[i]]] <- if_else(dat2$id == i, dat2[[var_nms[i]]],
                                NA_real_)
}

out <- dat2 %>%
  mutate(Var = do.call(coalesce, pick(contains("Var")))) %>%
  select(date, Var)

out
#> # A tibble: 15 x 2
#>    date         Var
#>    <date>     <dbl>
#>  1 2023-01-13 100. 
#>  2 2023-01-16 104. 
#>  3 2023-01-17 102. 
#>  4 2023-01-18 102. 
#>  5 2023-01-19  NA  
#>  6 2023-01-11  99.7
#>  7 2023-01-12  99.8
#>  8 2023-01-13  99.9
#>  9 2023-01-16  NA  
#> 10 2023-01-17  NA  
#> 11 2022-11-24 102. 
#> 12 2022-11-25  99.9
#> 13 2022-11-28  99.3
#> 14 2022-11-29 100. 
#> 15 2022-11-30 100.

Created on 2023-04-12 with reprex v2.0.2

Ответ принят как подходящий

Используя данные, показанные воспроизводимо в примечании в конце, предположим, что требуется объект зоопарка с отдельным столбцом для каждого столбца, не связанного с датой.

Сначала создайте вектор группировки g, который выглядит как c("Var1", "Var1", "Var2", "Var2", "Var3", "Var3"), а затем преобразуйте DF в список и разделите его на g, дающий s. Наконец, преобразуйте каждый компонент s в объект зоопарка и объедините их с помощью cbind. (Если требуется фрейм данных, используйте fortify.zoo в результате.)

library(zoo)

g <- rep(names(DF)[sapply(DF, is.numeric)], each = 2)
s <- split(as.list(DF), g)
do.call("cbind", lapply(s, function(x) read.zoo(as.data.frame(x))))

давая:

            Var1 Var2  Var3
2022-11-24    NA   NA 102.3
2022-11-25    NA   NA  99.9
2022-11-28    NA   NA  99.3
2022-11-29    NA   NA    NA
2022-11-30    NA   NA    NA
2023-01-11    NA 99.7    NA
2023-01-12    NA   NA    NA
2023-01-13 100.1 99.9    NA
2023-01-16 104.5 99.1    NA
2023-01-17 101.6 99.5    NA
2023-01-18 101.8   NA    NA
2023-01-19    NA   NA    NA

Это может быть представлено в виде конвейера следующим образом:

g <- rep(names(DF)[sapply(DF, is.numeric)], each = 2)
DF |>
  as.list() |>
  split(g) |>
  lapply(function(x) read.zoo(as.data.frame(x))) |>
  do.call(what = "cbind")

или

DF |>
  as.list() |>
  (\(x) split(x, rep(names(x)[sapply(x, is.numeric)], each = 2)))() |>
  lapply(\(x) read.zoo(as.data.frame(x))) |>
  do.call(what = "cbind")

Примечание

Lines <- "date1 Var1 date2 Var2 date3 Var3
2023-01-13 100.1 2023-01-11 99.7 2022-11-24 102.3
2023-01-16 104.5 2023-01-12 NA 2022-11-25 99.9
2023-01-17 101.6 2023-01-13 99.9 2022-11-28 99.3
2023-01-18 101.8 2023-01-16 99.1 2022-11-29 NA
2023-01-19 NA 2023-01-17 99.5 2022-11-30 NA"
DF <- read.table(text = Lines, header = TRUE)

на самом деле работает с этим примером, но при работе с моим набором данных я получаю следующее сообщение об ошибке: «Ошибка в read.zoo(as.data.frame(x)) : индекс имеет 206 неверных записей в строках данных: 348 349 ... "

Bertrand G 12.04.2023 15:03

Дубликата нет. Ошибка возникает из-за NA в конце моего набора данных. read.zoo не может читать из строк, заполненных NA. Я читал темы о разнице между пустыми ячейками и NA. Я пытался изменить их значение, используя различные стратегии, такие как na.fill() и другие параметры, такие как na = "". Но это не работает.

Bertrand G 13.04.2023 11:28

Проблема только в датах АН. NA в значениях не проблема. Замените as.data.frame(x) на na.omit(as.data.frame(x))

G. Grothendieck 13.04.2023 13:46

Другие вопросы по теме