【问题标题】:multiple time series graphs in one plot disregarding empty fields一个图中的多个时间序列图,不考虑空字段
【发布时间】:2017-07-26 20:20:53
【问题描述】:

我有一个问题可能很简单,但一直很难找到解决方案。 我有一个不同公司和不同年份的数据,如下所示:

我想在一个图中为所有公司绘制一种时间序列图。关键是我不希望相应间隔的缺失值为 0。我期望的结果将日期作为 X 轴,将值作为 Y 轴。因此,例如,CompanyA 的线的结果将是一条水平线,从 2001-02 开始,到 2001-06 结束,高度为 1000(作为 Y 值)。我想可视化不同公司的时间间隔。 我试图在 R 中使用 ggplot2 来绘制它,但并没有真正成功。有人可以帮我在R中画这个吗?我有 500 多行和 180 多列。

【问题讨论】:

  • 您好 Mina,您能否发布一个代码片段,以便我们查看您的工作内容?谢谢
  • 将来我建议您发布您的数据(如我的回答)而不是打印屏幕,以便其他人轻松帮助您。此外,正如@Justin 指出的那样,您应该展示您所做的努力(您尝试过但没有成功的代码,正如您在问题中提到的那样)。
  • @Mina 在你的问题中,你提到你有不同的年份,但对我来说是同一年,只是不同的日子或月份。你能澄清一下吗?
  • @aelwan 是的,我有 15 年的月度数据。在您建议的答案中,您假设格式是 Y-m-d...
  • @Mina 检查我的更新答案

标签: r ggplot2 timeserieschart


【解决方案1】:

这里有多个完全属于“数据争吵”的问题。最大的问题是将实际值估算到您的缺失值字段中。 幸运的是,xts 时间序列库包含执行此操作的函数,以及绘制多个时间序列的函数,这是您的最终目标。

但是,在我们可以使用这些奇妙的功能之前,您必须做一些工作,将您的数据转换为 xts 对象。

首先使用@aelwan的方法重新创建上面的数据。

    ```{r, tidy=TRUE}

    df <-  read.table(text = c(" 
    CompanyA    NA  1000    NA  NA  NA  1000
    CompanyB    600 NA  NA  NA  600 NA
    CompanyC    NA  5000    NA  5000 NA  NA"), 
                      header = F)   
    colnames(df) <-  c("CompanyName", "2001-01", "2001-02" ,"2001-03", "2001-04",  "2001-05", "2001-06")

    df

              CompanyName 2001-01 2001-02 2001-03 2001-04 2001-05 2001-06
            1    CompanyA      NA    1000      NA      NA      NA    1000
            2    CompanyB     600      NA      NA      NA     600      NA
            3    CompanyC      NA    5000      NA     500      NA      NA

您的数据似乎是宽格式,因此我建议将其转换为长格式。这将需要几个步骤来保留重要信息,例如列名和行名,以及数据的类别(数字)。

首先,转置数据框

df_t <- t(df)

现在,保存第一行,其中现在包含公司名称。

 company_names <- df_t[1,]

转置过程产生一个“矩阵”类的对象。删除第一行并制作 df_t 对象类 data.frame。

  df_t <- data.frame(df_t[-1, ], stringsAsFactors = FALSE)

添加存储在“company_names”中的公司名称作为列名

colnames(df_t) <- company_names

您的列数据类也可能在转置过程中丢失,因此请使用sapply 函数将所有列转换为数字类。

   df_long <- data.frame(sapply(df_t, FUN=as.numeric), row.names = rownames(df_t))

    # print the long form results
    df_long
```
        CompanyA CompanyB CompanyC
Jan 2001       NA      600       NA
Feb 2001     1000       NA     5000
Mar 2001       NA       NA       NA
Apr 2001       NA       NA     5000
May 2001       NA      600       NA
Jun 2001     1000       NA       NA

现在,将您的新df_long data.frame 转换为基于时间序列索引的xts 对象,以访问您需要的时间序列函数。

```{r}
library(xts)

# convert rownames "2001-01, 2001-02, ..." to yearmon format
rownames(df_long) <- as.yearmon(rownames(df_long), "%Y-%m")

# pass the dates as an index to the xts via the `order.by` arguement.
df_xts <- xts(df_long , order.by = as.yearmon(rownames(df_long)))
```

最后,我们可以使用xts包中的“Last Observation Carried Forward”功能,na.locf来填写日期。

```{r}
df_locf <- na.locf(df_xts)

df_locf
```
         CompanyA CompanyB CompanyC
Jan 2001       NA      600       NA
Feb 2001     1000      600     5000
Mar 2001     1000      600     5000
Apr 2001     1000      600     5000
May 2001     1000      600     5000
Jun 2001     1000      600     5000

xts 类的对象上调用plot 函数时,可以轻松生成多变量时间序列图。

```{r}
# The plot function works.
plot(df_locf)
```

【讨论】:

  • 感谢您的精彩回答。我在写数据时犯了一个错误。 4 月份公司 C 的值应该是 5000 而不是 500。您能否相应地更新您的答案。
  • 完成。谢谢
  • @Justin 非常感谢您非常详细的解释。这个解决方案正是我所需要的。我试图将您的过程应用于我的数据,但在执行 rownames(df_long) 步骤时,它显示不允许重复的“row.names”错误...我检查过,我的数据中没有这种重复...你能请帮我摆脱这种情况?如果有帮助,我会将我的数据集添加到我的问题中......
  • 如果保留日期不太重要,解决方案是跳过 rownames(df_long) 步骤并将该小节中的第二步修改为 read df_xts &lt;- xts(df_long , order.by = index(df_long))。这应该创建你的 xts obj
  • @Mina 希望这个解决方案对你有用!我注意到你更新的堆栈溢出,我想我会提到,如果你有一个令人满意的解决方案,最好将它标记为已回答。这样社区中的其他人就不必花时间阅读所有帖子,并且可以回答其他问题。谢谢
【解决方案2】:

您是否正在寻找这样的东西?

library(tidyverse)
library(zoo)
df %>% 
  tidyr::gather("date", "value", 2:7) %>% 
  dplyr::filter(!is.na(value)) %>% 
  ggplot(., aes(x = as.factor(as.yearmon(date)), y = value, group = CompanyName, colour = CompanyName))+
    geom_line() +labs(x = "Date")

数据

df <-  read.table(text =c("
CompanyA    NA  1000    NA  NA  NA  1000
CompanyB    600 NA  NA  NA  600 NA
CompanyC    NA  5000    NA  5000    NA  NA"), header = F) 

colnames(df) <-  c("CompanyName",   "2001-01",  "2001-02"   ,"2001-03", "2001-04",  "2001-05",  "2001-06")

【讨论】:

  • 谢谢@aelwan,但问题是:我的数据不是 Y-m-d 格式...它是 Y-m 格式...
猜你喜欢
  • 2015-08-27
  • 2013-09-19
  • 2017-11-05
  • 1970-01-01
  • 1970-01-01
  • 2019-12-02
  • 2019-04-05
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多