Построение среднемесячной температуры на ggplot с доверительными интервалами

Мне нужно построить среднюю месячную температуру и сократить месяц по оси x, и мне нужно добавить 95% доверительные интервалы, но не знаю, как это сделать. Любые визуальные эффекты CI были бы хороши.

Тогда мне нужно построить

Я разделил Date...Time на отдельные столбцы, но я не могу заставить ось X отображать сокращенный месяц с month.abb в ggplot.

Мне был предоставлен следующий набор данных (сокращенный для stackflow):

# Data
CleanTempSal = data.frame(
  stringsAsFactors = F,
    Date...Time = c(
        "1/31/2017 20:00",
        "1/31/2017 21:00",
        "1/31/2017 22:00",
        "1/31/2017 23:00",
        "2/1/2017 0:00",
        "2/1/2017 1:00",
        "2/1/2017 2:00",
        "2/1/2017 3:00",
        "3/21/2017 10:00",
        "3/21/2017 11:00",
        "3/21/2017 12:00",
        "3/21/2017 13:00"),

    Temp..C. = c(14.87, 14.77, 15.08, 15.08, 
                  14.96, 14.87, 15.05, 15.05, 
                  18.87, 19.32, 19.97, 20.44),

    Salinity.psu. = c(14.58, 14.52, 14.44, 14.46, 
                      14.56, 14.67, 14.78, 14.88, 
                      18.78, 18.81, 19.41, 19.16),

    Conduc.mS.cm. = c(19.33, 19.21, 19.26, 19.28,
                      19.34, 19.44, 19.66, 19.78, 
                      26.67, 26.96, 28.14, 28.09)
    )
Date...Time   Temp..C.  Salinity.psu.   Conduc.mS.cm.
1/31/2017 20:00 14.87   14.58   19.33
1/31/2017 21:00 14.77   14.52   19.21
1/31/2017 22:00 15.08   14.44   19.26
1/31/2017 23:00 15.08   14.46   19.28
2/1/2017 0:00   14.96   14.56   19.34
2/1/2017 1:00   14.87   14.67   19.44
2/1/2017 2:00   15.05   14.78   19.66
2/1/2017 3:00   15.05   14.88   19.78
3/21/2017 10:00 18.87   18.78   26.67
3/21/2017 11:00 19.32   18.81   26.96
3/21/2017 12:00 19.97   19.41   28.14
3/21/2017 13:00 20.44   19.16   28.09

И код.

library(tidyverse)
library(ggplot2)
library(lubridate)

# convert date column to date class
CleanTempSal$Date...Time <- as.POSIXct(CleanTempSal$Date...Time, format = "%m/%d/%y %H:%M")

#Add Month Column to data set
CleanTempSal <- CleanTempSal %>% mutate(month = month(Date...Time))
CleanTempSal <- CleanTempSal %>% mutate(month2 = month.abb[month])
CleanTempSal <- CleanTempSal %>% mutate(year = year(Date...Time))
CleanTempSal <- CleanTempSal %>% mutate(hour = hour(Date...Time))


#group by month and take the mean of that month
a <- CleanTempSal %>%
  group_by(month) %>%
  summarise(month_mean = mean(Temp..C.))

#plot mean monthly temp
ggplot(a, aes(month, month_mean)) +
  geom_point(aes(color = month_mean)) + 
  geom_line(aes(color = month_mean)) +
  scale_color_gradient("Temp", low = "blue", high = "red4") +
  labs(x = "Month of 2017",
       y = "Water Tempearture (C)",
       title = "Monthy Mean Water Temperature",
       subtitle = "NCBS Dock - Cedar Key, FL")

дает мне это

Предоставленные данные не дадут такой же график, поскольку я сократил его для простоты. Это даст только первые 3 месяца, и средства будут разными, но достигнуть тех же целей.

изображение вывода


person Johnny5ish    schedule 28.03.2020    source источник
comment
Спасибо @Rui Barradas   -  person Johnny5ish    schedule 28.03.2020
comment
Я заметил одну небольшую проблему: вам нужно %m/%d/%Y %H:%M преобразовать дату / время, заглавную букву «Y», так как год - это 4 цифры, а не 2.   -  person Ben    schedule 29.03.2020
comment
Прошу прощения, поскольку я сказал, что я новичок в этом, он был импортирован в R вот так ... Итак, нижний регистр y правильный, остальные данные взяты из excel. Я должен был быть более ясным. Дата ... Время Temp..C. Salinity.psu. Conduc.mS.cm. 1 13 января 17 0:00 14,65 24,19 30,52 2 13 января 17 1:00 14,93 24,23 30,76 3 13 января 17 2:00 14,99 24,28 30,86 4 13 января 17 3:00 14,65 24,35 30,70 5 1 / 13/17 4:00 14,68 24,35 30,72 6 13.01.17 5:00 14,65 24,35 30,70   -  person Johnny5ish    schedule 29.03.2020


Ответы (1)


Вот один из способов приблизиться к этому:

Чтобы получить аббревиатуры месяцев, я мог бы подумать о том, чтобы сохранить месяц как POSIXct. Используя floor_date, вы можете получить месяц для каждой временной точки и сохранить его в желаемом формате. При построении вы можете использовать scale_x_datetime и указать метку, которую вы хотите использовать на оси x. В этом случае %b предоставит аббревиатуру месяца.

Для определения доверительного интервала 95% необходимо рассмотреть различные подходы. Один из способов - вручную вычислить 95% доверительный интервал. Обратите внимание, что здесь сделаны предположения (на основе t-распределения Стьюдента). В этом случае я использовал geom_ribbon с некоторой прозрачностью (альфа .2), чтобы показать интервал между точками. В качестве альтернативы вы можете использовать stat_summary, который будет вычислять среднее значение и 95% ДИ и отображать в ggplot.

#group by month and take the mean of that month
a <- CleanTempSal %>%
  group_by(month = floor_date(Date...Time, unit = "month")) %>%
  summarise(month_mean = mean(Temp..C.),
            sd = sd(Temp..C.),
            n = n()) %>%
  mutate(se = sd / sqrt(n),
         lower.ci = month_mean - qt(1 - (.05/2), n - 1) * se,
         upper.ci = month_mean + qt(1 - (.05/2), n - 1) * se)

#plot mean monthly temp
ggplot(a, aes(x = month, y = month_mean)) +
  geom_point(aes(color = month_mean)) + 
  geom_line(aes(color = month_mean)) +
  geom_ribbon(aes(ymin = lower.ci, ymax = upper.ci), alpha = 0.2) +
  scale_color_gradient("Temp", low = "blue", high = "red4") +
  scale_x_datetime(date_breaks = "1 month", date_labels = "%b") +
  labs(x = "Month of 2017",
       y = "Water Tempearture (C)",
       title = "Monthy Mean Water Temperature",
       subtitle = "NCBS Dock - Cedar Key, FL")

Сюжет

график с 95% доверительным интервалом и метками xaxis с месяцами

Изменить (16.04.20):

Если у вас есть данные за несколько лет, при расчете SD и SE вы должны группировать как по месяцам, так и по годам:

group_by(month = floor_date(Date...Time, unit = "month"), year)

Кроме того, я изменил ggplot, чтобы вместо ленты отображались полосы ошибок. Внесены некоторые незначительные изменения для получения ширины полос ошибок, включая использование as.Date(month) и scale_x_date.

#group by month and take the mean of that month
a <- CleanTempSal %>%
  group_by(month = floor_date(Date...Time, unit = "month"), year) %>%
  summarise(month_mean = mean(Temp..C.),
            sd = sd(Temp..C.),
            n = n()) %>%
  mutate(se = sd / sqrt(n),
         lower.ci = month_mean - qt(1 - (.05/2), n - 1) * se,
         upper.ci = month_mean + qt(1 - (.05/2), n - 1) * se)

#plot mean monthly temp
ggplot(a, aes(x = as.Date(month), y = month_mean)) +
  geom_point(aes(color = month_mean)) + 
  geom_line(aes(color = month_mean)) +
  #geom_ribbon(aes(ymin = lower.ci, ymax = upper.ci), alpha = 0.2) +
  geom_errorbar(aes(ymin = month_mean - se, ymax = month_mean + se), width = 1) +
  scale_color_gradient("Temp", low = "blue", high = "red4") +
  scale_x_date(date_breaks = "1 month", date_labels = "%b %y") +
  labs(x = "Month",
       y = "Water Tempearture (C)",
       title = "Monthy Mean Water Temperature",
       subtitle = "NCBS Dock - Cedar Key, FL")

Сюжет

график с полосами погрешностей

Данные

CleanTempSal <- structure(list(Date...Time = structure(c(1485914400, 1485918000, 
1485921600, 1485925200, 1485928800, 1485932400, 1485936000, 1485939600, 
1490108400, 1490112000, 1490115600, 1490119200), class = c("POSIXct", 
"POSIXt"), tzone = ""), Temp..C. = c(14.87, 14.77, 15.08, 15.08, 
14.96, 14.87, 15.05, 15.05, 18.87, 19.32, 19.97, 20.44), Salinity.psu. = c(14.58, 
14.52, 14.44, 14.46, 14.56, 14.67, 14.78, 14.88, 18.78, 18.81, 
19.41, 19.16), Conduc.mS.cm. = c(19.33, 19.21, 19.26, 19.28, 
19.34, 19.44, 19.66, 19.78, 26.67, 26.96, 28.14, 28.09), month = c(1, 
1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3), month2 = c("Jan", "Jan", "Jan", 
"Jan", "Feb", "Feb", "Feb", "Feb", "Mar", "Mar", "Mar", "Mar"
), year = c(2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 2017, 
2017, 2017, 2017), hour = c(20L, 21L, 22L, 23L, 0L, 1L, 2L, 3L, 
10L, 11L, 12L, 13L)), class = "data.frame", row.names = c(NA, 
-12L))
person Ben    schedule 28.03.2020
comment
Большое спасибо, @Ben !!! В этом сообществе действительно классные люди. Насколько сложно было бы просто отображать их в виде полосок доверительного интервала для каждой точки вместо ленты? - person Johnny5ish; 29.03.2020
comment
Я бы использовал стандартную ошибку для стержней ... вы можете заменить geom_ribbon на это: geom_errorbar(aes(ymin = month_mean - se, ymax = month_mean + se)) - person Ben; 29.03.2020
comment
Бен Я использовал эту линию и был проинформирован, что я рассчитал доверительные интервалы для всего набора данных, а не по месяцам. какие-либо предложения? Кроме того, когда я пытался использовать полосы вместо ленты, она отображалась как линия, и я не мог отобразить верхнюю и нижнюю шляпы полос ошибок. - person Johnny5ish; 16.04.2020
comment
@ Johnny5ish SD и SE рассчитываются по месяцам, но если у вас есть данные за несколько лет, они будут группировать годы вместе для данного месяца. Может ли быть так? Если да, то вы можете group_by и месяц, и год. - person Ben; 16.04.2020
comment
@ Johnny5ish См. Отредактированный ответ выше. Это должно быть group_by и месяц, и год. Также есть пример с полосами погрешностей. Надеюсь, это поможет - если проблема не исчезнет, ​​дайте мне знать. - person Ben; 16.04.2020