привязывать столбцы различной длины, фильтруя наблюдения, которые не имеют общего индекса в R - PullRequest
0 голосов
/ 10 ноября 2018

У меня есть 6 объектов временных рядов, хранящихся в их собственном фрейме данных, каждый с индексом от 2000-01-01 до 2010-01-01, однако наблюдения для каждого объекта различны. Для пояснения, хотя каждый объект может иметь наблюдение за 2005-01-01, один объект может не иметь наблюдения за 2010-02-01, в то время как все 5 других имеют.

Я хочу использовать cbind, чтобы связать их все вместе, однако, поскольку каждый объект имеет различную длину, я не могу (и факт, что я хочу найти изменяющиеся во времени корреляции между каждым объектом). По сути, я хочу найти способ привязки «завершенных дел» только ко всем 6 объектам и поместить их в соответствующие области индекса.

Я думаю о создании фрейма данных с указателем времени в диапазоне от 2000-01-01 до 2010-01-01, привязав их к соответствующему индексу времени (это часть, которую я не знаю, как сделать) и затем использовать полные наблюдения, чтобы удалить наблюдения, которые не имеют общего индекса. Если есть лучший способ сделать это, уточнение также приветствуется!

Спасибо!

Ответы [ 3 ]

0 голосов
/ 10 ноября 2018

Вы можете пойти на full_join от dplyr. Я бы предложил загрузить tidyverse, на случай, если задача станет более сложной (см. Примеры ниже).

Пример кадра данных:

df1 <- data.frame(time = c("2012-01-01"), var_A = c(3))
df2 <- data.frame(time = c("2010-01-01", "2012-01-01"), var_B = c(3, 2))
df3 <- data.frame(time = c("2011-01-01", "2012-01-01"), var_C = c(0, 0))

Код:

library(tidyverse)

df <- df1 %>%
  full_join(df2, by = "time") %>%
  full_join(df3, by = "time")

Выход:

df

        time var_A var_B var_C
1 2012-01-01     3     2     0
2 2010-01-01    NA     3    NA
3 2011-01-01    NA    NA     0

Это также можно сократить:

library(tidyverse)

df <- list(df1, df2, df3) %>%
  reduce(full_join, by = "time")

Выход:

        time var_A var_B var_C
1 2012-01-01     3     2     0
2 2010-01-01    NA     3    NA
3 2011-01-01    NA    NA     0

Если вам это нужно, вы всегда можете использовать arrange впоследствии.

P.S. Если вам не хватает некоторых дат в этой последовательности в ваших фреймах данных, вы можете просто добавить несколько строк в оператор, чтобы дополнить их (я также добавил оператор replace, чтобы заполнить NA 0):

library(tidyverse)

list(df1, df2, df3) %>%
  reduce(full_join, by = "time") %>%
  mutate(time = as.Date(time)) %>%
  complete(time = seq.Date(as.Date("2000-01-01"), as.Date("2010-01-01"), by="month")) %>%
  replace(., is.na(.), 0)

В вышеприведенном случае я добавил последовательность от 2000-01-01 до 2010-01-01 по месяцам, но вы также можете изменить ее на min(time) и max(time) или что вам больше подходит.

0 голосов
/ 10 ноября 2018

В Base R вы могли бы сделать

merge( merge( df1, df2, all = TRUE ), df3, all = TRUE )

, что дает вам

        time var_A var_B var_C
1 2012-01-01     3     2     0
2 2010-01-01    NA     3    NA
3 2011-01-01    NA    NA     0
0 голосов
/ 10 ноября 2018

Один из способов сделать это:

1

Создать фрейм данных с полным временным диапазоном от 2000-01-01 до 2010-01-01.Для этого вы можете использовать seq().

2

. Используйте dplyr::left_join(), чтобы присоединить ваши различные фреймы данных к этому фрейму опорных данных (не забудьте указать фрейм опорных данных в качестве первого аргументаиз left_join()).

Изменить для пояснения комментария:

left_join необходимо «знать», как объединить кадры данных вместе.У вас есть два варианта:

  • вы можете дать такое же имя для колонки даты вашей системы отсчета обработки данных (так, например, если переменная дата ваших 6 кадров данных, называется «Дата», вашЕдинственный столбец фрейма данных также должен называться «Дата»)

  • или, если вы называете это как-то еще (например, «Ссылка»), вам нужно добавить by аргумент: left_join(df_ref, df1, by = c("Reference", "Date"))

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...