【问题标题】:Plotting multiple variables with the same name from different dataframes in a time series; ggplot2 tidyr从时间序列中的不同数据框中绘制多个具有相同名称的变量; ggplot2 tidyr
【发布时间】:2018-12-13 20:38:40
【问题描述】:

我重新开始使用 R 和 ggplot 来可视化环境变量的时间序列数据。到目前为止,我喜欢 ggplot2 可视化数据的机会,轻松选择不同的时期和变量来绘制和定义美学。但现在我遇到了第一个我无法用谷歌搜索的问题:

  • 我的目标是将来自不同数据帧的多个变量与个人美学(固定周期、相同 y 轴、不同颜色等)绘制到一个图中

我有 8 个数据帧 ("TreeA" - "TreeH") 结构如下,其中TreeA 是数据帧的名称,“时间”是测量时间,格式为POSIXct格式,TleafTairTdiff 是 16 个变量中的三个:

 TreeA
                         Zeit  Tleaf     Tair  Tdiff ........
       1: 2018-05-18 00:00:00 12.997 13.20000 -0.203   
       2: 2018-05-18 00:10:00 13.082 13.20000 -0.119     
       3: 2018-05-18 00:20:00 11.909 12.06700 -0.158   
       4: 2018-05-18 00:30:00 11.315 11.53300 -0.219     
       5: 2018-05-18 00:40:00 11.251 11.46700 -0.216

我已经 melted 将 DF 转换为长格式结果

TreeA_long
                      Time variable        value
    1: 2018-05-18 00:00:00    Tleaf        12.997000000
    2: 2018-05-18 00:10:00    Tleaf        13.082000000
    3: 2018-05-18 00:20:00    Tair         11.909
    4: 2018-05-18 00:30:00    Tair         11.315
    5: 2018-05-18 00:40:00    Tdiff         1.251

从这里我已经成功地用这个 ggplot 功能绘制图表:

ggplot(subset(TreeA_long, variable %in% c("Tleaf","Tair","Tdiff")),
       aes(x=Time,
           y=value, color=variable)) +
  geom_line() +
  scale_x_datetime(limits=start.endKW21, labels = date_format("%d") , breaks = date_breaks("24 hours")) +
  scale_y_continuous(limits = c(5,55),breaks = seq(10,55, by = 2)) +
  labs(title="Mai/Juni Cbet1", x="Day", y="Temperature") +
  theme(legend.position='right') +
  scale_color_manual(values = c("Tleaf" = "green", "Tair" = "blue", "Tdiff" = "yellow"))

我尝试添加第二个 geom_line(data=TreeB_long) 用于在同一图中从第二个 Dataframe 中绘制变量。它可以绘制来自TreeB 的所有变量,但当然我需要比较相同的变量,并且我还想为每个变量指定美学(线条的颜色、虚线等。

所以我的问题是:

  • 如何在一个 Plot 中比较 TreeATreeB
  • 我也会 打开以合并不同的数据框,但它不起作用 使用相同的变量名以长格式连接

我希望我的问题足够清楚,并且您能以某种方式帮助我。我相信有一个简单的方法可以解决我的问题,但正如我所说,谷歌搜索到目前为止并没有产生好的结果。

谢谢你,祝你有美好的一天! 康拉德

【问题讨论】:

  • 我认为您可能应该附加treeA-treeH 数据集,包括数据名称的指示变量(例如dplyr::bind_rows(tibble::lst(treeA, treeB, <...>, treeH), .id = "data")),然后melt() 并使用数据集指示符变量来构建你的情节。如果您需要更具体的建议,请提供reproducible example
  • 谢谢。我无法生成可重现的示例,因为我无法上传我的 *csv 输入。无论如何,在您的大力帮助下,我离解决方案只有一步之遥:使用dplyr::bind_rows,我得到一个数据框,其中data 列表示测量值是否属于treeA, treeB,...。我可以告诉 'melt()' 函数从各自的列 Tleaf,Tair... 中提取 variable 列的名称,并将其与来自 melt()data 列结合起来,生成一个带有变量列的长数据集条目treeATleaf, treeBTleaf,...
  • 你不能直接用melt()做那个;但是如果你愿意,你可以在melt() 之后将datavariable 列一起paste() 来实现。但是,将两者分开可能是一个好主意:这将允许更轻松地控制绘图的美学。我添加了一个答案,展示了我将在此处采用的方法。
  • 顺便说一句,如果您需要创建一个包含复杂/大数据的示例,最好使用dput(head(data)) 轻松生成读取一小部分数据所需的代码.
  • 好的,谢谢。我如何告诉 aes 函数从两列中提取信息?

标签: r plot ggplot2 time-series tidyr


【解决方案1】:

因此,根据 Mikko Marttila 的建议,我使用 tibble::lstdplyr::bind_rows 将所有(已经加载了 8 个数据帧(treeA,...,treeF)的数据帧绑定在一起,从而产生了一个新的 DF:

Liste <- lst (treeA,treeB,treeC,treeD,treeE,treeG,treeH)
new   <- bind_rows(Liste, .id="Test")

    >         Test                Time  Tleaf     Tair   ....
    >     1: treeA 2018-05-18 00:00:00 12.997 13.20000 
    >     2: treeA 2018-05-18 00:10:00 13.082 13.20000 
    >     3: treeA 2018-05-18 00:20:00 11.909 12.06700 
.....
    >   300: treeH 2018-05-18 00:30:00 11.315 11.53300 
    >   301: treeH 2018-05-18 00:40:00 11.251 11.46700 

在此之后使用 reshape2::melt 并将两列定义为 id.Vars 会产生一个包含 4 列的长数据框

long <-melt(new, id.vars = c("Time", "Test"))

     long
                           Time  Test variable        value
         1: 2018-05-18 00:00:00 treeA    Tleaf 12.997000000
         2: 2018-05-18 00:10:00 treeA    Tleaf 13.082000000
         3: 2018-05-18 00:20:00 treeA    Tleaf 11.909000000
...
       300: 2018-05-18 00:30:00 treeH    Tleaf 11.315000000
       301: 2018-05-18 00:40:00 treeH    Tleaf 11.251000000

最后将 ZeitTest 列通过 tidyr::unite 组合产生一个长格式数据框,其中包括我来自 8 个输入数据框的所有数据:

long2 <- unite(long, variable, c(Test, variable), remove=TRUE)

long2
                       Zeit       variable        value
     1: 2018-05-18 00:00:00    treeA_Tleaf 12.997000000
     2: 2018-05-18 00:10:00    treeA_Tleaf 13.082000000
     3: 2018-05-18 00:20:00    treeA_Tleaf 11.909000000
...
   300: 2018-05-18 00:30:00    treeH_Tleaf 11.315000000
   301: 2018-05-18 00:40:00    treeH_Tleaf 11.251000000

有了这些,我就可以使用 ggplot2 来识别和加载来自不同来源的绘图值。如果有更简单的方法可以实现这一点,请在 cmets 中告诉我。我也认为可能会有使用基础包更多功能的解决方案。但是由于我需要完成工作,所以我不介意加载很多包。请注意,此处粘贴的数据是为了可视化结构。

【讨论】:

    【解决方案2】:

    我认为您可能应该附加 treeA-treeH 数据集,包括数据名称的指示变量(例如dplyr::bind_rows(tibble::lst(treeA, treeB, &lt;...&gt;, treeH), .id = "data")),然后是melt(),并使用数据集指示变量来构建您的绘图。

    这是一个简化的示例。首先,让我们读入您提供的数据:

    txt <- "Date Time  Tleaf     Tair  Tdiff
    2018-05-18 00:00:00 12.997 13.20000 -0.203
    2018-05-18 00:10:00 13.082 13.20000 -0.119
    2018-05-18 00:20:00 11.909 12.06700 -0.158
    2018-05-18 00:30:00 11.315 11.53300 -0.219
    2018-05-18 00:40:00 11.251 11.46700 -0.216"
    
    treeA <- read.table(text = txt, header = TRUE,
                        stringsAsFactors = FALSE)
    

    为了示例,我还创建了一个 treeB 数据集只需向 treeA 添加一些噪声即可:

    library(dplyr)
    library(ggplot2)
    
    set.seed(1)
    n <- nrow(treeA)
    
    treeB <- treeA %>%
      mutate_if(is.numeric, function(x) x + rnorm(n))
    

    我们现在可以使用bind_rows() 和附加两个数据集 添加一个变量以显示原始数据框。

    tree <- tibble::lst(treeA, treeB) %>%
      bind_rows(.id = "data") %>%
      mutate(dttm = as.POSIXct(paste(Date, Time)))
    

    在绘图之前,将数据重新整形为长格式很有用, 正如你之前所做的那样:

    tree_long <- reshape2::melt(tree, measure = c("Tleaf", "Tair", "Tdiff"))
    

    现在我们准备好绘图了。您要使用的布局的选择将 当然取决于您要强调的数据的哪个方面;例如, 如果不同tree 数据集之间的比较感兴趣,它可能 最好使用 facetting 来比较每个变量中的 trees:

    ggplot(tree_long, aes(dttm, value, color = data)) +
      facet_wrap(~ variable, scales = "free_y", ncol = 1) +
      geom_line()
    

    reprex package (v0.2.0.9000) 于 2018 年 7 月 9 日创建。

    【讨论】:

    • 非常感谢您的帮助。在手动做很多工作之前我很短。分面对我的数据来说也是一个好主意。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-12-02
    • 1970-01-01
    • 1970-01-01
    • 2022-01-08
    • 2019-06-14
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多