【问题标题】:R Time Series Gap Fill for plotting with type = 'b'R时间序列间隙填充用于绘制类型='b'
【发布时间】:2014-08-02 02:35:49
【问题描述】:

我有一个 .csv 文件,其中包含四列(NAME、ID、YEAR、VALUE,请参见下面的示例),并希望使用 plot('YEAR', 'VALUE', type = 'b') 绘制一些时间序列图. 由于缺少时间序列中年份之间的一些数据,我想编写包含年份之间的 NA 值的新列,以便我可以绘制数据而无需在 YEAR 间隙中连接线(在我的示例中:填写 NA 值1984 年到 1987 年在 BATLEY 项目中)。

有没有办法做到这一点?任何帮助将不胜感激!谢谢!

我的 .csv 文件如下所示:

NAME;                ID;      YEAR; VALUE
NAME1;              885;    1988;      -2
NAME1;              885;    1989;       0
NAME2;  2665;   1999;       4
NAME2;  2665;   2000;       8
NAME2;  2665;   2001;      19
NAME2;  2665;   2002;      13
NAME2;  2665;   2003;      13
NAME3;          893 ;   1983;       0
NAME3;          893 ;   1988;       2
NAME3;          893 ;   1989;      -1
NAME4;              877 ;   1972;      -1
NAME5;          894 ;   1973;      -3

【问题讨论】:

  • 那不是csv文件。
  • 这只是我的 csv 外观的一个示例。如果您知道解决方案,如果您能提供帮助,那就太好了。谢谢!

标签: r plot time-series na


【解决方案1】:

您可以使用 sep=";" 来读取您所显示的文件在 read.csv 中识别单独的值。 您可能会考虑使用类似下面的代码来读取数据、修复日期、添加 NA 并绘制绘图。我将您的数据放在一个名为“plot_test.txt”的文件中,因此 read.csv 从那里获取数据。另外,根据您对 BATLEY 项目的评论,我假设您想为情节中的每个项目分开行。

# read data file into xx and change character years to Date values
xx <- read.csv("plot_test.txt",header=TRUE,sep=";")
xx$YEAR <- as.Date(paste(as.character(xx$YEAR),"-01-01",sep=""))

#    create df as a template for all years and names
date_seq <- seq(min(xx$YEAR),max(xx$YEAR),by="12 month")
df <- merge(data.frame(NAME=unique(xx$NAME),ID=unique(xx$ID)),data.frame(YEAR=date_seq,VALUE=NA),all=TRUE)

# create unique names in xx and df to merge on
xx$NAME_YR <- paste(xx$NAME,xx$YEAR,sep="")
df$NAME_YR <- paste(df$NAME,df$YEAR,sep="")
#  merge keeping only real data columns and restore original column names
xy <- merge(xx, df,by="NAME_YR",all=TRUE)[,c("NAME.y","ID.y","YEAR.y","VALUE.x")]
names(xy) <- names(xx)[1:4]

# plot xy using ggplot
library(ggplot2)
sp <- ggplot(data=xy, aes(x=YEAR, y=VALUE, colour=NAME)) + geom_point() + geom_line()
plot(sp)  

【讨论】:

  • 非常感谢您的回答。这几乎就是我想要的。
  • 还有一个问题:有没有一种方法可以在绘图时在 x 轴上显示不是整个范围(例如 xlim)?之后,我将图分开并绘制单个 xy 图,大多数范围是从 1960 年到 2010 年,但我也有一些数据范围从 1885 年到 1900 年。当单独绘制所有内容时,这会导致 y 轴调整到数据范围和x 轴没有。有办法吗?
  • 好的。我们将使 platting 数据有点不同,可能更接近您最初要求的数据,并且他们将每个 NAME 绘制在具有自己时间轴的单独图表中
  • 很高兴听到您想通了。在 R 中总是有多种方法可以做事,特别是如果您使用额外的包,但这坚持 R 基础和通用 R 函数。
【解决方案2】:

很高兴听到你想通了。我仍然想知道每页的情节数量。我在代码中添加了几行,以允许您设置显示在一页上的绘图的行数和列数,然后根据需要循环遍历尽可能多的绘图页。我还添加了一些 ggplot 东西来改变绘图文本的外观。

    # read data file into xx and change character years to Date values
    xx <- read.csv("plot_test.txt",header=TRUE,sep=";")
    xx$YEAR <- as.Date(paste(as.character(xx$YEAR),"-01-01",sep=""))
    xx$NAME_YR <- paste(xx$NAME,xx$YEAR,sep="")

    #  create Year template for years between min and max years for each NAME
    xxmin <- as.Date(tapply(xx$YEAR, xx$NAME, min ), origin="1970-01-01")
    xxmax <- as.Date(tapply(xx$YEAR, xx$NAME, max ), origin="1970-01-01")
    xxdates <- mapply(seq, xxmin, xxmax, by="12 month")
    xxyears <- data.frame(NAME=rep(names(xxdates), sapply(xxdates, length)), 
                          YEAR=as.Date(unlist (xxdates),origin="1970-01-01"))
    xxyears$NAME_YR <- paste(xxyears$NAME,xxyears$YEAR,sep="")

    #  merge  template and data and assign colnames to ploting data
    xy <- merge(xx, xxyears, by="NAME_YR", all=TRUE)[,c("NAME.y","ID","YEAR.y","VALUE")]
    names(xy) <- c("NAME","ID","YEAR","VALUE")

   # plot each NAME in a separate chart with own time axis
   library(ggplot2)
   rows_pg <- 2   # number of rows of plots per page
   cols_pg <- 2   # number of columns of plots per page
   chts_pg <- rows_pg*cols_pg
   num_plots <- nlevels(xy$NAME)
   #  set plot axis labels and main titles and set values for text
   spttl <- ggtitle("Your plot title\nSecond line of your plot title")
   spaxlb <- labs ( x="Year", y="Data Values")  
   spth <-  theme(plot.title=element_text(size=16, face="bold", colour="blue") )
   spth <-  spth + theme(axis.title.x= element_text(size=14, colour="blue") )
   spth <-  spth + theme(axis.title.y = element_text(size=14, colour="blue") )
   spth <-  spth + theme(axis.text = element_text(size=14, colour="black") )
   spth <-  spth + theme(strip.text = element_text(size=14, colour="brown"))
   #  generate plots
   for( iplt in seq(1,num_plots, chts_pg) )  {
     sp <- ggplot(data=xy[xy$NAME %in% levels(xy$NAME)[iplt:(iplt+chts_pg-1)], ],
                  aes(x=YEAR, y=VALUE)) + geom_line() + geom_point()
     sp  <- sp + facet_wrap(~ NAME, scales="free_x", nrow=rows_pg, ncol=cols_pg)
     plot(sp + spttl + spaxlb + spth)
   }

【讨论】:

  • 不,这正是我的目标,谢谢。最后,我想将绘图写入以 NAME 为标题和 ID 为 ps 文件名的后记。
  • 在合并过程中出现以下错误:fix.by(by.x, x) 中的错误:“'by' 必须指定唯一有效的列”。我该怎么办?
  • 太好了,非常感谢您的帮助!自己仔细阅读代码后想通了!
猜你喜欢
  • 1970-01-01
  • 2016-05-07
  • 2016-11-29
  • 1970-01-01
  • 2015-02-28
  • 1970-01-01
  • 2022-01-24
  • 1970-01-01
  • 2014-11-02
相关资源
最近更新 更多