изменить набор данных ежедневных временных рядов с днями в качестве переменной

#r #reshape

#r #изменить

Вопрос:

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

 structure(list(Year = c(1994, 1995, 1996, 1997, 1998, 1999, 2000, 
2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 
2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019, 2020, 1994, 1995, 
1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 
2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016), 
    Month = c(1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
    1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 
    2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2), day1 = c(0, 
    0, 0, 0, 31, 0, 0, 0, 0, 0, 0, 0, 0, 7.4, 0, 0, 28.2, 0, 
    0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1.4, 
    18.6, 0, 0, 0, 56, 2, 0, 0.4, 0, 0, 0, 0, 0), day2 = c(0, 
    0, 0, 0, 8.4, 0, 0, 0, 65.2, 0, 0, 0, 0, 0, 0, 0, 41, 0, 
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5.2, 0, 0, 0, 0, 0, 0, 0, 
    6.8, 0, 0, 0, 0, 10.6, 0, 9.2, 0, 0, 0, 0, 21.6), day3 = c(0, 
    0, 0, 0, 0, 0, 0, 0, 132.4, 0, 0, 0, 0, 0, 0, 0, 0, 1.2, 
    0, 10.2, 0, 0, 1.6, 0, 0, 0, 0, 0, 0, 7.4, 0, 0, 0, 5.2, 
    7.8, 0, 2.6, 43.4, 0, 0, 0, 0, 2.6, 0, 0, 0, 0, 0, 0, 6.2
    ), day4 = c(0, 0, 0, 0, 0, 0, 15.6, 0, 34.6, 0, 0, 0, 0, 
    0, 0, 0, 81, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 13.1, 0, 0, 0, 
    0, 0, 0, 53.2, 4, 0, 2.4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6.8, 
    0), day5 = c(0, 0, 0, 0, 0, 0, 12.4, 0, 1.2, 0, 0, 0, 0, 
    21, 0, 0, 5, 1, 0, 0, 0, 47, 0, 0, 0, 0, 9.2, 0, 2, 0, 0, 
    0, 0, 0, 0, 0, 0, 10.2, 0, 3, 0, 0, 0.6, 0, 0, 0, 0, 0, 11.4, 
    0), day6 = c(8.6, 0, 0, 0, 0, 0, 17.2, 0, 9.4, 0, 0, 0, 0, 
    0, 0, 0, 0, 0, 0, 0, 0.4, 0, 0, 0, 0, 0, 5.4, 30.5, 61, 0, 
    0, 0, 0, 0, 0, 0, 0, 11.4, 0, 5.7, 0, 0, 5.8, 0, 0, 0, 0, 
    0, 0, 0), day7 = c(0, 0, 8.4, 0, 0, 0, 42, 0, 0, 0, 0, 0, 
    0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 5.2, 0, 0, 0, 0, 0, 0, 0, 0, 
    0, 0, 0, 0, 0, 0, 0.2, 0, 0.8, 0, 0, 0, 0, 0, 0, 0, 7, 0, 
    0), day8 = c(2, 0, 0, 3, 0, 0, 26.4, 0, 12.8, 0, 0, 0, 0, 
    0, 0, 0, 0, 0, 0, 0, 0, 0, 43, 0, 0, 0, 2, 0, 0, 0, 0, 0, 
    0, 1.8, 0, 0, 5.8, 13.2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
    0), day9 = c(0, 0, 0, 0, 0, 0, 17.2, 0, 7.6, 0, 1, 0, 0, 
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 14, 0, 23, 0, 0, 0, 12, 
    0, 0, 72.6, 0, 0, 0, 0, 0, 0, 0, 3, 0, 6.6, 0, 0, 0, 19.4, 
    0, 0), day10 = c(0, 0, 0, 0, 0, 8.2, 10.8, 0, 0, 0, 2.2, 
    0, 0, 0, 0, 0, 10, 0, 0, 0, 0, 0, 10, 0, 0, 0, 0, 0, 2.5, 
    0, 19.4, 0, 2.4, 0, 0, 2.4, 0, 0, 0, 0, 0, 0, 0, 0.2, 0, 
    0, 1.4, 0, 0, 0.4), day11 = c(0, 0, 0, 0, 1.6, 64, 0, 0, 
    1.6, 0, 29, 0, 0, 0, 0, 0, 16.2, 12.8, 0, 0, 0, 0, 0, 0, 
    0, 0, 0, 0, 27.5, 0, 0, 0, 0, 1.4, 0, 0, 0, 0, 0, 0, 0, 0, 
    0, 0, 0, 0, 0, 17.6, 0, 0), day12 = c(0, 0, 0, 0, 0, 0, 0, 
    0, 22.4, 0, 41.6, 0, 0, 2, 0, 0, 0.2, 17.6, 0, 0, 0, 0, 0, 
    0, 5.6, 0, 0, 0, 0, 23, 0, 0, 3.6, 0, 1.8, 1.2, 14.6, 0, 
    81.8, 0, 1.4, 4.4, 33, 2.4, 0, 0, 0, 1.6, 0, 0), day13 = c(0, 
    0, 3, 3.2, 0, 0, 0, 4.2, 0, 0, 6, 0, 0, 2.4, 0, 0, 0, 1, 
    0, 0, 0, 0, 0, 0, 0, 0, 0, 5.8, 0, 0, 0, 0, 54.2, 0, 0, 6.2, 
    16.4, 10, 0, 0, 6.6, 0, 101.2, 0, 0, 0, 0, 0, 0, 0), day14 = c(0, 
    0, 0, 9, 12.2, 0, 0, 0, 2.6, 0, 26.4, 60.6, 0, 0, 0, 0, 0, 
    0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 75, 9, 0, 0, 6.8, 0, 6.4, 0, 
    7.8, 0, 0, 0, 0, 16.2, 0, 6, 0, 50, 0, 0, 1.4, 0, 0), day15 = c(0, 
    0, 0, 0, 0, 0, 0, 0, 11.2, 0, 8.6, 0, 0, 0, 0, 0, 0, 0, 0, 
    0, 0, 0, 2.8, 0, 2.2, 0, 0, 6.2, 0, 0, 0, 0, 0, 4.2, 0, 0, 
    0, 0, 0, 0, 50.8, 0, 0, 0.4, 21.8, 0, 23, 0, 0, 0), day16 = c(0, 
    0, 0, 0, 0, 0, 11.2, 0, 3.2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 33.4, 0, 0, 0, 
    0, 16.6, 0.6, 0.6, 0, 0, 0, 3.4, 21.6, 0, 0, 0, 0), day17 = c(0, 
    0, 0, 0, 0, 0, 0, 0, 10.4, 0, 0, 0, 0, 0, 0, 11.2, 0, 0, 
    0, 14.2, 0, 0, 0, 0, 0, 0, 0, 1.5, 11, 0, 0, 0, 0, 1.2, 0, 
    0, 0, 0, 1, 1, 20.6, 0, 0, 0, 22.2, 2.6, 0, 2.4, 0, 0), day18 = c(60.6, 
    0, 0, 0, 0, 0, 0, 0, 28.8, 0, 0.4, 0, 0, 0, 0, 0, 1.2, 0, 
    0, 0, 0, 0, 9, 0, 0, 5.4, 1.4, 0, 0, 0, 0, 59.6, 11.8, 5.6, 
    0, 0, 0, 0, 0, 42, 26, 0, 0, 0, 0, 12, 17.8, 1.2, 0, 0), 
    day19 = c(30, 0, 9.8, 0, 1.2, 0, 0, 0, 1.6, 17.2, 50.6, 0, 
    0, 0, 0, 0, 16.2, 0, 4.2, 0, 0, 0, 13.4, 0, 1.4, 0, 0, 3.2, 
    0, 0, 0, 1.2, 32, 0, 0, 0, 0, 0, 0, 29.8, 19.6, 0, 0, 0, 
    0, 6.4, 1, 0, 1, 0), day20 = c(0, 0, 0, 0, 0, 0, 0, 0, 0, 
    43.4, 2, 4.4, 0, 0, 0, 0, 4.8, 10, 18.8, 0, 7, 0, 1.6, 0, 
    46, 0, 0, 70, 5, 0, 16.2, 0, 0, 0, 0, 0, 15.2, 0, 0, 0, 18.4, 
    0, 21, 0, 2, 60, 0, 0, 5.6, 0), day21 = c(0, 0, 2, 0, 1.8, 
    47, 0, 0, 0, 22.8, 7.4, 0, 0, 0, 0, 0, 35, 11.4, 0, 6, 0, 
    0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
    0, 0, 1.4, 0, 46, 8.4, 0, 0, 0, 0), day22 = c(72, 0, 0, 23, 
    0, 0, 0, 0, 31.6, 1.6, 15.4, 0, 0, 0, 0, 10.6, 0.6, 12.8, 
    3, 0, 0, 0, 16, 0, 0, 0, 18.2, 4, 0, 0, 6.4, 0, 0, 1.2, 0, 
    0, 9.8, 0, 0, 0, 2.2, 0, 12.2, 0, 1, 0, 0, 0, 1.4, 0), day23 = c(1.2, 
    0, 0, 10, 0, 0, 0, 0, 3.4, 0, 0, 0, 0, 0, 10, 37, 0, 39, 
    2, 0, 0, 0, 6.2, 19.2, 0, 7.6, 0, 0, 0, 0, 0, 0, 2.4, 0.6, 
    0, 0, 4.2, 0, 0, 32, 15, 0, 6.8, 0, 0, 0, 0, 0, 18.6, 0), 
    day24 = c(0, 0, 0, 4.2, 0, 0, 0, 0, 0, 8.4, 14.8, 1.2, 0, 
    0, 8.4, 20.4, 0, 17, 0, 0, 0, 0, 30.8, 0, 9, 0, 21.6, 0, 
    0, 25.4, 0, 0, 0, 8.6, 0, 0, 41.4, 0, 0, 6.4, 20.8, 21.6, 
    22.6, 23.6, 0.8, 4, 0, 0, 0, 4.6), day25 = c(0, 0, 0, 0, 
    0, 0, 0, 0, 1, 9.2, 32, 0, 0, 0, 0, 0, 0, 2.4, 16, 0, 0, 
    0, 4, 0, 1.6, 0, 0, 0, 0, 26, 0, 0, 0, 4.2, 0, 0, 1.8, 6, 
    0, 25.2, 10.2, 0, 0, 0.4, 0, 0, 0, 0, 0, 0), day26 = c(0, 
    0, 0, 44, 0, 0, 0, 0, 0, 0, 56.6, 0.6, 0, 0, 2, 0, 0, 11.2, 
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
    13, 0, 4.6, 4.4, 26.6, 0, 0, 54.4, 0, 0, 0, 0, 0), day27 = c(0, 
    0, 0, 0, 10.6, 0, 0, 0, 0, 22.6, 45.4, 0, 0, 0, 15.4, 0, 
    2.6, 0.4, 0, 0, 0, 0, 0, 0, 2.4, 0, 0, 0, 0, 0, 0, 0, 0, 
    3.4, 0, 0, 16.8, 14.2, 0, 8.8, 0, 0, 1.8, 0, 0, 4.8, 0, 0, 
    0, 0), day28 = c(0, 0, 0, 7.4, 0, 0, 0, 6.2, 0, 39.4, 39.2, 
    0, 0, 0, 0, 0, 0, 8.6, 0, 0, 0, 0, 0.2, 0, 0, 0, 0, 0, 0, 
    0, 0, 2.4, 0, 0, 2.8, 0, 7.2, 23.2, 0, 0, 0, 2.4, 0.2, 0, 
    0, 0, 0, 9.6, 0, 0), day29 = c(0, 0, 0, 0, 0, 0, 0, 0, 0, 
    0, 0.8, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, NA, 
    NA, 0, NA, NA, NA, 0.8, NA, NA, NA, 0, NA, NA, NA, 0, NA, 
    NA, NA, 0, NA, NA, NA, 0), day30 = c(0, 0, 0, 26.6, 0, 0, 
    0, 0, 0, 0, 8.2, 0, 0, 0, 0, 1.4, 0, 0.6, 12.2, 0, 4.8, 0, 
    0, 0, 0.6, 0, 0, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, 
    NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA), day31 = c(0, 
    102, 0, 0, 2.4, 0, 0, 0, 2.4, 0, 47, 0, 0, 0, 25, 0, 0, 0, 
    0, 0, 0, 0, 0, 0, 0, 0, 0, NA, NA, NA, NA, NA, NA, NA, NA, 
    NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA
    )), row.names = c(NA, 50L), class = "data.frame")
  

Если я использую функцию melt, она не будет учитывать количество дней в месяце, вводя значения NA в неправильные даты, такие как 1994-02-30. Я мог бы удалить строки со значениями NA, но мне нужно быть уверенным, что в моем наборе данных нет никакого значения NA.

 melt(Data,c("Year","Month")))
  

Мой желаемый результат был бы таким:

 Data<- 
Date         Value
1994-01-01     0.1
1994-01-02       0
1994-01-03      12 
  

Ответ №1:

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

 library(dplyr)
library(tidyr)

df %>%
  pivot_longer(cols = starts_with('day'), 
               values_drop_na = TRUE) %>%
  mutate(name = readr::parse_number(name)) %>%
  unite(Date, Year, Month, name, sep = '-') %>%
  mutate(Date = as.Date(Date))

# A tibble: 1,487 x 2
#   Date       value
#   <date>     <dbl>
# 1 1994-01-01   0  
# 2 1994-01-02   0  
# 3 1994-01-03   0  
# 4 1994-01-04   0  
# 5 1994-01-05   0  
# 6 1994-01-06   8.6
# 7 1994-01-07   0  
# 8 1994-01-08   2  
# 9 1994-01-09   0  
#10 1994-01-10   0  
# … with 1,477 more rows
  

Комментарии:

1. Но если бы у меня были значения NA с истинными датами? Я потеряю их, используя values_drop_na.

2. Ммм … тогда не используйте values_drop_na = TRUE ? и если вы хотите отбрасывать NA значения только в Date , используйте filter(!is.na(Date)) . Это не сработает?