【问题标题】:R how to plot multiple graphs (time-series)R如何绘制多个图(时间序列)
【发布时间】:2019-10-28 00:16:01
【问题描述】:

我有一个数据框df

ID      Final_score appScore pred_conf pred_chall obs1_conf obs1_chall obs2_conf obs2_chall exp1_conf exp1_chall
3079341 4           low      6         1          4         3           4        4          6         2 
3108080 8           high     6         1          6         1           6        1          6         2 
3130832 9           high     2         6          3         4           5        4          6         2 
3148118 10          high     4         4          4         4           5        4          6         2 
3148914 10          high     2         2          2         5           2        5          6         2 
3149040 2           low      5         4          6         4           6        4          6         4 

Q1:我想为 _conf_chall 功能的 appScore highlow 创建两个叠加图。我想让这些图表有不同的颜色。我怎样才能做到这一点?

Q2:是否可以绘制两张平滑图,一张用于所有_conf 变量/特征,一张用于所有_chall 特征。 请注意,我的列没有时间变量,而是按以下顺序排列:

pred_conf  --> obs1_conf  --> obs2_conf  --> exp1_conf
pred_chall --> obs1_chall --> obs2_chall --> exp1_chall

这只是一个玩具示例,实际数据有几行多列。作为参考,我在下面分享 dput():

dput(df)
structure(list(ID = c(3079341L, 3108080L, 3130832L, 3148118L, 3148914L, 3149040L), 
Final_score = c(4L, 8L, 9L, 10L, 10L, 2L), 
appScore = structure(c(2L, 1L, 1L, 1L, 1L, 2L), .Label = c("high", "low"), class = "factor"), 
pred_conf = c(6L, 6L, 2L, 4L, 2L, 5L), 
pred_chall = c(1L, 1L, 6L, 4L, 2L, 4L), 
obs1_conf = c(4L, 6L, 3L, 4L, 2L, 6L), 
obs1_chall = c(3L, 1L, 4L, 4L, 5L, 4L), 
obs2_conf = c(4L, 6L, 5L, 5L, 2L, 6L), 
obs2_chall = c(4L, 1L, 4L, 4L, 5L, 4L), 
exp1_conf = c(6L, 6L, 6L, 6L, 6L, 6L), 
exp1_chall = c(2L, 2L, 2L, 2L, 2L, 4L)), 
class = "data.frame", row.names = c(NA, -6L))

以下帖子很有帮助,但它们考虑了时间变量。我应该如何使用某种时间变量来更改我的任务名称?

Plotting multiple time-series in ggplot

Multiple time series in one plot

更新 1:

当为highlow appScore 组中的_conf 绘制时,我的图表目前看起来像这样。我想对这些图表进行平滑和叠加,看看是否有任何差异或模式。

这是我用过的代码

library(ggplot2)
df_long %>% 
  filter(part == "conf") %>% 
  ggplot(aes(feature, val, group = appScore)) +
  geom_line() +
  geom_point() +
  facet_wrap(~appScore, ncol = 1) +
  ggtitle("conf")

更新 2:

使用脚本:

test_long %>% 
  ggplot(aes(feature, val, color = appScore, group = appScore)) + #, size = Final_score)) +
  geom_smooth() +
  facet_wrap(~part, nrow = 1) +
  ggtitle("conf and chall")

我已经能够生成所需的图表:

【问题讨论】:

  • 在您的案例中时间变量的作用是什么? “我的列没有时间变量,而是按顺序排列的”-据我所知,〜时间〜是功能名称的第一部分(obs1在pred之后,obs2在obs1之后,依此类推)。但是在这个代码块autoplot(ts(df$pred_conf))中,ID是时间变量。
  • @laroslav 您的理解是正确的,它与您在代码中的编写方式一致。 pred 然后 obs1 然后 obs2 然后 exp1。我分享的代码块只是为了展示我的尝试。

标签: r plot time-series smoothing


【解决方案1】:

首先我会将数据转换为长格式。

library(tidyr)
library(dplyr)

df_long <- 
  df %>% 
  pivot_longer(
    cols = matches("(conf|chall)$"),
    names_to = "var",
    values_to = "val"
  )

df_long

#> # A tibble: 48 x 5
#>         ID Final_score appScore var          val
#>      <int>       <int> <fct>    <chr>      <int>
#>  1 3079341           4 low      pred_conf      6
#>  2 3079341           4 low      pred_chall     1
#>  3 3079341           4 low      obs1_conf      4
#>  4 3079341           4 low      obs1_chall     3
#>  5 3079341           4 low      obs2_conf      4
#>  6 3079341           4 low      obs2_chall     4
#>  7 3079341           4 low      exp1_conf      6
#>  8 3079341           4 low      exp1_chall     2
#>  9 3108080           8 high     pred_conf      6
#> 10 3108080           8 high     pred_chall     1
#> # … with 38 more rows

df_long <-
  df_long %>% 
  separate(var, into = c("feature", "part"), sep = "_") %>% 
  # to ensure the right order
  mutate(feature = factor(feature, levels = c("pred", "obs1", "obs2", "exp1"))) %>% 
  mutate(ID = factor(ID))

df_long
#> # A tibble: 48 x 6
#>    ID      Final_score appScore feature part    val
#>    <fct>         <int> <fct>    <fct>   <chr> <int>
#>  1 3079341           4 low      pred    conf      6
#>  2 3079341           4 low      pred    chall     1
#>  3 3079341           4 low      obs1    conf      4
#>  4 3079341           4 low      obs1    chall     3
#>  5 3079341           4 low      obs2    conf      4
#>  6 3079341           4 low      obs2    chall     4
#>  7 3079341           4 low      exp1    conf      6
#>  8 3079341           4 low      exp1    chall     2
#>  9 3108080           8 high     pred    conf      6
#> 10 3108080           8 high     pred    chall     1
#> # … with 38 more rows

现在绘图很容易。例如绘制"conf" 特征:

library(ggplot2)
df_long %>% 
  filter(part == "conf") %>% 
  ggplot(aes(feature, val, group = ID, color = ID)) +
  geom_line() +
  geom_point() +
  facet_wrap(~appScore, ncol = 1) +
  ggtitle("conf")

【讨论】:

  • 非常感谢,我已经能够运行您的脚本。请问是否可以叠加这些图然后平滑它们?我想这样做,以便我可以根据 appScore 的高低来比较数据。正如我在代码中更新的那样: df_high = df[which(df$appScore == 'high') , ] df_low = df[which(df$appScore == 'low') , ]
  • 要覆盖挑战和配置功能?删除filter 行并将aes 设置为aes(feature, val, group = part, color = part)。你需要什么样的平滑?
  • @laroslav 非常感谢您的留言!我想覆盖appScorehigh 的所有ID 的_conf 图,然后将其与appScorelow 的其他ID 进行比较。
  • @Sandy 我已经更新了代码。它是否接近您的需求?
  • @laroslav 我接受您的代码作为答案,因为它极大地帮助了我入门。感谢您的帮助。