Создание последовательности дат в виде нового столбца в кадре данных R - PullRequest
0 голосов
/ 18 января 2020

Я боролся с простой задачей (наверное).

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

Мои входные данные выглядят так:

Lon      Lat      Year    Start_date     End_date    

70.25    40.25    2000    10/01/2009     04/30/2010  

70.75    40.25    2000    05/01/2010     08/30/2010   

71.00    40.25    2000    07/07/2010     11/30/2010   

Вот что я хотел бы получить:


Lon       Lat    Year     start_date  end_date      Sequence

70.25    40.25    2000    10/01/2009   04/30/2010   10,11,12,1,2,3,4

70.75    40.25    2000    05/01/2010   08/30/2010   5,6,7,8

71.00    40.25    2000    07/01/2010   11/30/2010   7,8,9,10,11

Где последний столбец содержит список всех месяцы (как число) между датой начала и конца.

Это мой предварительный код.

sequence <- Map(seq.dates, start_date, end_date, by = "months", format = "%m/%d/%y")

Код работает нормально и дает мне список всех месяцев от начала до конца, к чему я стремился. Однако я не в состоянии справиться со списком, так как не могу найти хорошего способа извлечь значения списка в новый столбец информационного кадра, сохранив при этом структуру (уровни). Я попробовал почти любой предложенный в stackoverflaw способ извлечения значений из списка, и ничего не работает. Итак, я хочу начать все сначала и изменить перспективу.

Есть ли другой способ изменить указанную выше функцию таким образом, чтобы создать новый столбец, присоединенный к моим данным, или вектор? И НЕ СПИСОК? Любая помощь будет очень цениться. Спасибо!

Ответы [ 2 ]

0 голосов
/ 18 января 2020

Мы можем использовать spread из tidyr, что также будет работать, если версия tidyr не является текущей

library(dplyr)
library(tidyr)
df %>%
   mutate_at(vars(ends_with("date")), as.Date, format = "%m/%d/%Y") %>%
   mutate(month = map2(Start_date, End_date,
                      ~as.integer(format(seq(.x, .y, by = "month"), "%m")))) %>%
   unnest(cols = month) %>%
   mutate(temp = 1) %>% 
   spread(month, temp, fill = 0)

data

df <- structure(list(Lon = c(70.25, 70.75, 71), Lat = c(40.25, 40.25, 
40.25), Year = c(2000L, 2000L, 2000L), Start_date = structure(c(3L, 
1L, 2L), .Label = c("05/01/2010", "07/07/2010", "10/01/2009"), class = "factor"), 
End_date = structure(1:3, .Label = c("04/30/2010", "08/30/2010", 
"11/30/2010"), class = "factor")), class = "data.frame", row.names = c(NA,-3L))
0 голосов
/ 18 января 2020

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

library(tidyverse)

df %>%
  mutate_at(vars(ends_with("date")), as.Date, format = "%m/%d/%Y") %>%
  mutate(month = map2(Start_date, End_date,
                     ~as.integer(format(seq(.x, .y, by = "month"), "%m")))) %>%
  unnest(cols = month) %>%
  mutate(temp = 1) %>%
  pivot_wider(names_from = month, values_from = temp, 
             values_fill = list(temp = 0)) %>%
  select(names(df), as.character(1:12))

# A tibble: 3 x 17
#    Lon   Lat  Year Start_date End_date     `1`   `2`   `3`   `4`   `5`
#  <dbl> <dbl> <int> <date>     <date>     <dbl> <dbl> <dbl> <dbl> <dbl>
#1  70.2  40.2  2000 2009-10-01 2010-04-30     1     1     1     1     0
#2  70.8  40.2  2000 2010-05-01 2010-08-30     0     0     0     0     1
#3  71    40.2  2000 2010-07-07 2010-11-30     0     0     0     0     0
# … with 7 more variables: `6` <dbl>, `7` <dbl>, `8` <dbl>, `9` <dbl>,
#   `10` <dbl>, `11` <dbl>, `12` <dbl>

данные

df <- structure(list(Lon = c(70.25, 70.75, 71), Lat = c(40.25, 40.25, 
40.25), Year = c(2000L, 2000L, 2000L), Start_date = structure(c(3L, 
1L, 2L), .Label = c("05/01/2010", "07/07/2010", "10/01/2009"), class = "factor"), 
End_date = structure(1:3, .Label = c("04/30/2010", "08/30/2010", 
"11/30/2010"), class = "factor")), class = "data.frame", row.names = c(NA,-3L))
...