【问题标题】:How can I convert this dataframe into a multiple time series object in R?如何将此数据框转换为 R 中的多个时间序列对象?
【发布时间】:2020-06-21 00:31:55
【问题描述】:

我正在尝试清理有关 COVID19 新型冠状病毒的一些数据 (https://github.com/CSSEGISandData/COVID-19/blob/master/csse_covid_19_data/csse_covid_19_time_series/time_series_19-covid-Confirmed.csv) 以进行各种类型的分析(即,创建一个具有 100 例病例的国家图表,或跟踪一段时间内的死亡率每个国家/地区)。我使用了以日期为列,以国家为行的数据。我转置了 Dataframe,以便得到每个国家/地区的一列和一列日期,如下所示。

我试图通过以下代码将此数据帧作为时间序列对象读取:

covid19ts = ts(covid19, frequency = 365, start = c(2020,22))

结果如下。我没有将日期作为我的索引列,而是得到一个 1 - 47 之间的数字(记录的天数)。这导致我无法创建图表或进行任何有意义的分析。

我还使用 lubridate 包尝试了以下代码,结果相同:

covid19ts = ts(covid19, frequency = 365, start= decimal_date(as.Date("2020-01-22")))

如何将我的 ts 日期转换为实际日期以供图表和分析?

或者我可以使用一种完全不同的方法来更好地进行分析?

感谢您的帮助。

【问题讨论】:

    标签: r dataframe date time-series


    【解决方案1】:

    您可以将数据保留为数据框并进行有用的绘图。也许以长格式获取数据。

    library(tidyverse)
    df <- read.csv('https://raw.githubusercontent.com/CSSEGISandData/COVID-19/master/csse_covid_19_data/csse_covid_19_time_series/time_series_19-covid-Confirmed.csv', check.names = FALSE)
    df1 <- df %>% pivot_longer(cols = -(1:4)) 
    head(df1)
    
    # A tibble: 6 x 6
    #  `Province/State` `Country/Region`   Lat  Long name    value
    #  <fct>            <fct>            <dbl> <dbl> <chr>   <int>
    #1 Anhui            Mainland China    31.8  117. 1/22/20     1
    #2 Anhui            Mainland China    31.8  117. 1/23/20     9
    #3 Anhui            Mainland China    31.8  117. 1/24/20    15
    #4 Anhui            Mainland China    31.8  117. 1/25/20    39
    #5 Anhui            Mainland China    31.8  117. 1/26/20    60
    #6 Anhui            Mainland China    31.8  117. 1/27/20    70
    

    如果您想将数据转换为帖子中显示的时间序列,您可以这样做:

    df2 <- df1 %>%
             group_by(`Country/Region`, name) %>%
             summarise(value = sum(value)) %>%
             pivot_wider(names_from = `Country/Region`, values_from = value, 
             values_fill = list(value = 0))
    
    ts_data <- xts::xts(df2[-1], as.Date(df2$name, "%m/%d/%y"))
    

    @G 建议的替代解决方案。格洛腾迪克依赖zoo

    z <- read.zoo(df1[c(2, 5:6)], index = "name", split = "Country/Region", 
                  format = "%m/%d/%Y", aggregate = sum)
    

    read.zoo 避免了 tidyverse 的所有显式聚合和重塑。然后我们可以使用autoplot 函数来绘制这个zoo 对象。

    【讨论】:

    • df2 &lt;- ... 开始的代码考虑library(dplyr); library(tidyr); library(xts); library(ggplot2); library(scales); z &lt;- read.zoo(df1[c(2, 5:6)], index = "name", split = "Country/Region", format = "%m/%d/%Y", aggregate = sum); autoplot.zoo(z[, colSums(z) &gt; 10000], facet = NULL) + scale_y_log10()
    • @G.Grothendieck 哇...看起来很酷。虽然我不完全明白那里发生了什么。添加为单独的答案?
    • read.zoo 读取文件或数据框,使用index= 命名的列作为时间创建动物园对象。它默认为Date 类,它使用format= 来解释日期。如果指定了split,则假定输入为长格式,并且在split= 中指定名称的列以宽格式标识列。它应用aggregate=(此处为sum)中指定的函数来聚合具有相同列和日期的单元格,以便日期是唯一的。 autoplot.zoo 使用 ggplot2 绘制一个动物园对象。 facet=NULL 表示不要使用单独的面板。
    【解决方案2】:

    与其使用tsxts 对象,不如使用这种tsibble 格式。

    library(tidyverse)
    library(tsibble)
    library(feasts)
    
    covid19 <- read_csv("time_series_19-covid-Confirmed.csv") %>%
      pivot_longer(cols = -(1:4)) %>%
      mutate(date = lubridate::mdy(name)) %>%
      select(-name) %>%
      rename(
        "Region" = `Province/State`,
        "Country" = `Country/Region`
      ) %>%
      as_tsibble(key = c(Region, Country), index = date)
    
    # Plot by country
    covid19 %>%
      filter(Country %in% c("China", "Italy", "Iran", "South Korea")) %>%
      group_by(Country) %>%
      summarise(value = sum(value)) %>%
      autoplot(value)
    

    reprex package (v0.3.0) 于 2020-03-09 创建

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-06-25
      • 1970-01-01
      • 2021-07-27
      • 2021-10-29
      • 2021-09-23
      • 2018-09-12
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多