【问题标题】:ggplot plotting empty monthsggplot 绘制空月
【发布时间】:2020-10-22 05:27:39
【问题描述】:

我对 R 还是很陌生,一直在努力寻找解决方案。

我有一个列表,其中包含与每个月对应的 12 个数据框。 (Data$January、Data$February 等)。

每个数据框都包含该月在某个年份范围内的时间序列数据。我想可视化这些数据,但是当我尝试使用 ggplot 时

ggplot(Data$January, aes(x = `Date`, y = `WaterLevel`)) +  
   geom_point()   

显示 1 月份的数据,但该图显示年份跨度,但包括 2 月至 12 月的空白月份。反正有没有让情节只显示一月?

数据的结构是:

'data.frame':15412 obs。 13 个变量:

$ 日期:日期,格式:“2006-01-01”“2006-01-02”“2006-01-03”“2006-01-04”...

$ 站 : chr "NBS01" "NBS01" "NBS01" "NBS01" ...

$ Station.Id : 编号 324 324 324 324 324 324 324 324 324 324 ...

$ Water_level: num 201 203 203 203 203 206 206 208 208 208 ...

$ 等效项:num NA NA NA NA NA NA NA NA NA NA ...

$ site_id:数字 324 324 324 324 324 324 324 324 324 324 ...

$ POSIXct:POSIXct,格式:“2006-01-01”“2006-01-02”“2006-01-03”“2006-01-04”...

$ wtr_lvlp : 数字 186 190 191 191 191 ...

$ equiv_p : 数量 0.683 0.711 0.699 0.691 0.681 ...

$ wtrlvl_Diff : 数字 14.8 12.9 12.3 11.8 11.6 ...

$ equiv_Diff : 数量 0.683 0.711 0.699 0.691 0.681 ...

$ wtrlvl_RMSE : 数字 84.1 84.1 84.1 84.1 84.1 ...

$ equiv_RMSE : num NA NA NA NA NA NA NA NA NA NA ...

编辑 3:dp(head(data$January))

structure(list(Date = structure(c(13149, 13150, 13151, 13152, 
13153, 13154), class = "Date"), Station = c("NBS01", 
"NBS01", "NBS01", "NBS01", "NBS01", "NBS01"
), Station.Id = c(324, 324, 324, 324, 324, 324), Water_level = c(201, 
203, 203, 203, 203, 206), Equivalent = c(NA_real_, 
NA_real_, NA_real_, NA_real_, NA_real_, NA_real_), site_id = c(324, 
324, 324, 324, 324, 324), POSIXct = structure(c(1136073600, 1136160000, 
1136246400, 1136332800, 1136419200, 1136505600), class = c("POSIXct", 
"POSIXt"), tzone = "UTC"), wtr_lvlp = c(186.2000028, 190.1000028, 
190.7000028, 191.2000028, 191.4000029, 191.6000029), equiv_p = c(0.682899983, 
0.711299982, 0.699199982, 0.690699983, 0.681199983, 0.672699983
), wtrlvl_Diff = c(14.79999723, 12.89999717, 12.29999716, 11.79999715, 
11.59999715, 14.39999714), equiv_Diff = c(0.682899983, 0.711299982, 
0.699199982, 0.690699983, 0.681199983, 0.672699983), wtrlvl_RMSE = c(84.1300149026027, 
84.1300149026027, 84.1300149026027, 84.1300149026027, 84.1300149026027, 
84.1300149026027), equiv_RMSE = c(NA_real_, NA_real_, NA_real_, 
NA_real_, NA_real_, NA_real_)), row.names = 1097:1102, class = "data.frame")

【问题讨论】:

  • 答案可能很大程度上取决于Data 的结构和内容。你能提供给我们Data$January吗?最简单的方法是将dput(Data$January) 的输出复制并粘贴到问题中。
  • 当然,但是它很长。请给我一秒钟来编辑帖子。
  • dput(head(Data$January)) 如果很长也可以,否则。
  • 谢谢,OP。根据你分享的内容,这个情节很好:ggplot(df, aes(x = Date, y = Water_level)) + geom_point()。请注意,您在列名周围有单引号,并且“Water_level”与您的数据集有拼写错误。这是这里的问题吗?
  • 不,我很抱歉。我在顶部错误地输入了我的代码(WaterLevel 而不是 Water_level),但它在 R 中是正确的。出现的图显示了我想要的数据,是的,但是我假设的年份之间有空格是因为该情节考虑到 2 月至 12 月。因此,1 月的数据在交互中看起来是压缩的和垂直的,我希望它们分散开来。我也尝试过 facet_grid() 但我仍然遇到同样的问题,即显示全年的数据似乎是这样的。

标签: r ggplot2


【解决方案1】:

在您的示例中,您只提供了 2006 年的数据,因此我们无法观察到您的问题。我用虚拟数据扩展了您的数据框,以包含 2007 年 1 月的值。我也只保留您在绘图中使用的两列

df <- structure(list(Date = structure(c(13149, 13150, 13151, 13152, 13153, 13154,13514,13515,13516,13517,13518,13519), class = "Date"), 
                     Water_level = c(201, 203, 203, 203, 203, 206, 211,213,213,213,213,216)), row.names = 1:12, class = "data.frame")

因为您的 Date 列是日期格式,ggplot 将此列中的数据解释为日期,并将绘制点考虑到它们之间的实际时间差。也就是说,如果您在日期“2006-01-01”处有一个点,而在日期“2007-01-01”处有另一个点,则在图中它们将相隔 365 天(应该如此),并且两者之间的日期将出现在xlabel。

ggplot(df, aes(x = Date, y = Water_level)) + geom_point()   

根据您的问题,您似乎希望将不同年份 1 月份的数据在视觉上连接起来,以便“2007-01-01”紧跟在“2006-01-31”之后。

快速而肮脏的解决方案

实现此目的的一种快速方法是将日期列转换为因子(分类变量)。执行此操作时,您的第一个日期将是分类变量中的第一个级别,第二个日期将是您的第二个级别,依此类推。由于您只有 1 月的日期,这将导致“2007-01-01”紧跟在“2006-01-31”之后。

# transform Date column to categorical variable
df$Date <- as.factor(df$Date) 

# plot again
ggplot(df, aes(x = Date, y = Water_level)) + geom_point()   

此解决方案速度很快,但也存在一些缺陷。首先,将这些不同的日期串联起来可能会让某些人感到困惑。此外,如果您的数据集跳过几天(例如从“2006-01-05”到“2006-01-15”),这些点将连续出现在您的图中(因为它们将是连续的“类别”)。此外,您可能需要使用 xaxis 中的标签,因为它们最终会相互重叠。

更好的解决方案(在我看来)

更好的解决方案是使用数据的年份创建另一列(使用带有日期的原始数据框),然后在不同方面绘制每一年。

# this package helps to do manipulations with dates
library(lubridate)

#create column with year
df$year <- year(df$Date)

#create plots separating each year in a different facet (scales = "free_x" is important!)
ggplot(df, aes(x = Date, y = Water_level)) + geom_point() + facet_wrap(vars(year), scales="free_x")  

希望这会有所帮助!

【讨论】:

    【解决方案2】:

    我认为我们可以像这样重现相关的数据结构:

    set.seed(69)
    
    df <- data.frame(Date = as.Date("2006-01-01") + lubridate::days(0:3651),
                     Water_level = cumsum(runif(3652, -0.2, 0.2)) + 200)
    
    Data <- split(df, month.name[lubridate::month(df$Date)])
    

    现在我们在一个列表中有 12 个数据框。每个数据框以一个月命名,但跨越数年。

    所以你的情节大概是这样的:

    library(ggplot2)
    
    ggplot(Data$January, aes(x = Date, y = Water_level)) +  
      geom_point()   
    

    但我们可以通过在每个帧中添加月份和年份列,然后分面来修复它:

    library(lubridate)
    
    Data <- lapply(Data, function(x) { x$month <- month.name[month(x$Date)]; x})
    Data <- lapply(Data, function(x) { x$year  <- year(x$Date); x})
    
    ggplot(Data$January, aes(x = Date, y = Water_level)) +  
      geom_point() +
      facet_grid(cols = vars(year), scales = "free")
    

    reprex package (v0.3.0) 于 2020 年 7 月 1 日创建

    【讨论】:

    • 重建数据结构的大师回来了! cumsum(runif...)) 太棒了!
    猜你喜欢
    • 2012-10-17
    • 2020-07-01
    • 2019-03-13
    • 2020-10-08
    • 2021-02-24
    • 1970-01-01
    • 2019-08-01
    • 2018-11-11
    • 2023-03-13
    相关资源
    最近更新 更多