无法计算 ggplot 分面中每天的平均值?

Unable to calculate mean for each day in ggplot facet?

提问人:Ginko-Mitten 提问时间:11/5/2023 最后编辑:Ginko-Mitten 更新时间:11/5/2023 访问量:46

问:

我的数据集

我有一个数据集speedtest.csv,如下所示:


Date,Time,Download,Upload
2023/10/01,00:00:00,34957192.9969772,20046840.2637393
2023/10/01,00:20:00,35826556.3982541,36143231.5378943
2023/10/01,00:40:00,27695436.936076,4957720.87281617
...
...
2023/10/02,01:00:00,22575345.5295727,10335897.5917135
2023/10/02,01:20:00,15805169.0654657,6179704.32589804
2023/10/02,01:40:00,31638270.9069979,15951432.6154521
...
...
2023/10/03,05:00:00,31366450.4288069,4476811.81028971
2023/10/03,05:20:00,10709016.6772629,8848402.0645949
2023/10/03,05:40:00,32722858.0348491,2045099.79491319
...
...

我当前的代码

下面给出的是我当前的代码,它能够使用 ggplot 中的分面处理和输出数据。在本练习中,我尝试使用管道在单个代码块中生成 ggplot。

library(tidyverse)

df<-read.csv("speedtest.csv", header = TRUE)

df%>%
  select(Date,Time, Upload, Download)%>%
  pivot_longer(cols = c("Upload", "Download"),
               names_to = "Parameter", values_to = "Value")%>%
  mutate(Date = as.POSIXct(Date, format = "%Y/%m/%d"),
         Time = as.POSIXct(Time, format = "%H:%M:%S"))%>%
  ggplot(aes(x=Time, y=(Value/8000000), colour=Parameter))+
  geom_line()+
  geom_point()+
  facet_wrap(~Date, ncol = 3, nrow = 2)+
  scale_colour_manual(values = c("blue","orange"))+
  scale_x_datetime(date_breaks = "4 hours",
                   date_labels = "%H:%M")+
  xlab("Time")+
  ylab("Speed (Mbyte/s)")+
  ylim(c(0,5))+
  theme_bw()+
  theme(strip.background = element_blank(),
        legend.position = "bottom",
        panel.grid = element_line(linetype = "dashed"))

ggsave("Speedtest_Figure.png")


电流输出

这将产生如下所示的输出:

Current_output

请求的更改

是否可以在每个方面添加文本,例如:

Mean Download: NNN
Mean Upload: MMM

其中 NNN 和 MMM 是每天的平均下载和上传速度,每个方面都会发生变化。如果可能的话,我想在单个代码块中,在管道内执行此操作。

我的尝试

我采用了非最佳方法,即创建不同的对象,然后用于在图中输入信息。geom_text

我创建了一个单独的对象Mean.dat

Mean.dat<-df%>%
  select(Date,Time, Upload, Download)%>%
  mutate(Date = as.POSIXct(Date, format = "%Y/%m/%d"),
         Time = as.POSIXct(Time, format = "%H:%M:%S"))%>%
  group_by(Date)%>%
  summarise(mean(Download)/8000000)

然后将此位添加到主代码中:

  geom_text(data=Mean.dat,
            aes(x=14, y=5, label=`mean(Download)/8e+06`), 
            colour="black", inherit.aes=FALSE, hjust = -1)

但是我收到错误消息:

Error: Invalid input: time_trans works with objects of class POSIXct only

其他资源

我参考了以下来源:

在 ggplot2 中将文本添加到 X 轴上的日期的多面绘图中

使用 ggplot2 创建一个facet_wrap图,每个图中都有不同的注释

使用每个分面的观测值数注释 ggplot2 分面

如何在每个方面添加注释

向每个分面添加唯一的文本 ggplot

我曾尝试在以前的尝试中修改代码,但日期时间问题似乎持续存在。

补遗

为了使代码更具可重现性,我被要求使用 提供我的数据片段。dput()

这是dput(df[c(1:5, 10:15, 20:25, 30:35, 40:41),])

structure(list(Date = c("2023/11/04", "2023/11/04", "2023/11/04", 
"2023/11/04", "2023/11/04", "2023/11/04", "2023/11/04", "2023/11/04", 
"2023/11/04", "2023/11/04", "2023/11/04", "2023/11/04", "2023/11/04", 
"2023/11/04", "2023/11/04", "2023/11/05", "2023/11/05", "2023/11/05", 
"2023/11/05", "2023/11/05", "2023/11/05", "2023/11/05", "2023/11/05", 
"2023/11/05", "2023/11/05"), Time = c("13:05:32", "13:20:03", 
"13:40:05", "14:20:03", "14:40:03", "17:20:03", "17:40:02", "18:20:03", 
"18:40:03", "19:20:04", "19:40:03", "22:20:03", "22:40:03", "23:20:03", 
"23:40:03", "00:20:03", "00:40:03", "03:20:03", "03:40:03", "04:20:03", 
"04:40:03", "05:20:03", "05:40:03", "08:20:03", "08:40:03"), 
    Download = c(34957192.9969772, 35826556.3982541, 27695436.936076, 
    32785866.6580349, 34373754.7935802, 29644745.5493678, 31936459.8397868, 
    32782764.8827361, 31366450.4288069, 10709016.6772629, 32722858.0348491, 
    34821984.5787153, 28379214.5120736, 26820887.0474698, 31839780.4165726, 
    32066886.2373525, 33440458.6440393, 28113353.9035434, 26284377.6573347, 
    29154520.6902359, 34918254.2123446, 21598680.1274404, 20700752.1868799, 
    34638409.416459, 34572097.5993048), Upload = c(20046840.2637393, 
    36143231.5378943, 4957720.87281616, 15688120.7580889, 35845959.9473685, 
    18072485.390123, 9069468.67273845, 6973860.4270036, 4476811.81028971, 
    8848402.0645949, 2045099.79491319, 23198345.7376053, 31702122.0677866, 
    11711052.7340582, 12556196.1275965, 28941390.4693129, 21543697.8944099, 
    12966120.4632239, 28660937.1396553, 28476185.8084195, 16678584.8862002, 
    29032008.7959507, 17276854.3732636, 36479144.7960276, 37478780.5131303
    )), row.names = c(1L, 2L, 3L, 4L, 5L, 10L, 11L, 12L, 13L, 
14L, 15L, 20L, 21L, 22L, 23L, 24L, 25L, 30L, 31L, 32L, 33L, 34L, 
35L, 40L, 41L), class = "data.frame")
R 日期时间 ggplot2 方面

评论

0赞 stefan 11/5/2023
当您使用时,您必须将 geom_text 中的 x 位置指定为日期时间,即 行不通。scale_x_datetimex=14
0赞 stefan 11/5/2023
如需更多帮助,请通过以下方式共享数据片段,提供最小的可重现示例dput()
0赞 Ginko-Mitten 11/5/2023
@stefan:我也试过了,但遇到了同样的错误。x="14:00"
1赞 stefan 11/5/2023
"14:00"是字符串,而不是日期时间。试用x = as.POSIXct("14:00", format = "%H:%M")
0赞 Ginko-Mitten 11/5/2023
@stefan:这成功了!我如何将您标记为正确答案或给您加分?

答:

2赞 stefan 11/5/2023 #1

正如我在评论中已经提到的,第二种方法的问题在于,您还必须将标签的轴值指定为日期时间,即 do .xx = as.POSIXct("14:00", format = "%H:%M")

但是,正如您提到的,您首选或最佳方法是在一个管道中执行所有计算,而不是使用第二个数据集,下面是一种使用 a 添加标签的方法。stat_summary

library(tidyverse)

df %>%
  select(Date, Time, Upload, Download) %>%
  pivot_longer(
    cols = c("Upload", "Download"),
    names_to = "Parameter", values_to = "Value"
  ) %>%
  mutate(
    Date = as.POSIXct(Date, format = "%Y/%m/%d"),
    Time = as.POSIXct(Time, format = "%H:%M:%S")
  ) %>%
  ggplot(aes(x = Time, y = (Value / 8000000), colour = Parameter)) +
  geom_line() +
  geom_point() +
  stat_summary(
    data = ~filter(.x, Parameter == "Download"),
    geom = "text",
    aes(
      x = as.POSIXct("14:00", format = "%H:%M"),
      y = stage(Value / 8000000, after_stat = 5),
      label = after_stat(round(y, 2))
    ),
    fun = mean, show.legend = FALSE
  ) +
  facet_wrap(~Date, ncol = 3, nrow = 2) +
  scale_colour_manual(values = c("blue", "orange")) +
  scale_x_datetime(
    date_breaks = "4 hours",
    date_labels = "%H:%M"
  ) +
  xlab("Time") +
  ylab("Speed (Mbyte/s)") +
  ylim(c(0, 5)) +
  theme_bw() +
  theme(
    strip.background = element_blank(),
    legend.position = "bottom",
    panel.grid = element_line(linetype = "dashed")
  )