我有两个数据框,一个是自1880-2023年以来每年每个月的全球平均气温记录,另一个是整齐格式的二次型模型(即每个月一列,截距一列,模型估计两列(Beta和Beta平方).

我想把每个月特定的二次函数叠加到每年每个月的温度记录上.

您可以通过tidytuesday R包访问我使用过的数据:

library(tidytuesdayR)
library(tidyverse)

tuesdata <- tidytuesdayR::tt_load(2023, week = 28)
global_temps <- tuesdata$global_temps

以下是清理和准备数据的代码:

# Clean data

global_temps <- global_temps |> 
  janitor::clean_names()

# Pivot

global_temps <- global_temps |> 
    pivot_longer(
        c(jan:dec),
        names_to = "month",
        values_to = "temperature"
    ) |> 
    select(
      year, 
      month, 
      temperature
    ) |> 
  mutate(
    month = (str_to_title(month))
  )

# Order months

month_order <- c(
  "Jan", "Feb", "Mar", "Apr", "May", "Jun", 
  "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
)

global_temps <- global_temps |> 
  mutate(
    month = factor(month, levels = month_order)
  )

此部分计算每个月的二次函数:

# Model the increase in temperature with a quadratic term

global_temp_quad <- global_temps |> 
  group_by(month) |> 
  nest() |> 
  mutate(
    model = map(data, ~ lm(temperature ~ poly(year, 2, raw = TRUE), data = .x))
  )

global_temp_quad <- global_temp_quad |>
  mutate(
    coef = map(model, broom::tidy)
  ) |> 
  unnest(coef) |> 
  select(
    term,
    estimate
  )

# Pivot wider

global_temp_quad <- global_temp_quad |> 
  pivot_wider(
    names_from = term,
    values_from = estimate
  ) |> 
  rename(
    intercept = "(Intercept)",
    year = "poly(year, 2, raw = TRUE)1",
    year_2 = "poly(year, 2, raw = TRUE)2"
  ) |> 
  ungroup()

这是使用上面提供的两个数据框创建绘图的代码:

ggplot() +
  geom_point(
    data = global_temps,
    aes(
      x = year,
      y = temperature
    ), 
    show.legend = FALSE,
    size = 1.5,
    alpha = 1,
    shape = 1
  ) +
  theme_light() +
  labs(
    title = "Global surface temperatures (1890-2023)",
    subtitle = "Temperature is recorded as deviation from the mean temperature for 1890-1950",
    source = "Data from NASA/GISS",
    x = NULL,
    y = "Deviation from mean temperature (Celsius)"
  ) +
  facet_wrap(~ month) +
  geom_function(
    data = global_temp_quad,
    aes(
      group = interaction(month)
    ),
    color = "red",
    alpha = 0.7,
    show.legend = FALSE,
    fun = function(x) {
      global_temp_quad$intercept +
      global_temp_quad$year * x +
      global_temp_quad$year_2 * x^2
    }
  ) +
  theme(
    panel.grid.minor = element_blank(),
    panel.grid.major.y = element_blank(),
    panel.grid.major.x = element_blank(),
    axis.ticks = element_blank()
  ) +
  scale_x_continuous(
    breaks = seq(1890, 2020, 40)
  ) +
  scale_y_continuous(
    limits = c(-0.5, 1.5)
  )

现在,如果有人能解决我的问题,我将不胜感激:

How can I model each function to be specific to the month in the facet_wrapped ggplot2 plot?

推荐答案

对于geom_function,您不会有任何运气,因为这需要对每个面板应用same函数,但您需要 for each 面板应用separate函数.

我会自己创建曲线数据,并向曲线图中添加线条:

curve_data <- global_temps |>
  group_by(month) |>
  summarize(first = min(year), last = max(year), .groups = "keep") |>
  inner_join(global_temp_quad |> 
               select(month, i = intercept, b1 = year, b2 = year_2),
             "month") |>
  reframe(xx = seq(first, last, length.out = 100),
          i, b1, b2) |>
  mutate(month, xx, yy = i + b1 * xx + b2 * xx ^ 2, .keep = "none")

## assume p is your plot without the geom_function part
## (just made the line thicker to see it better)
p +
  geom_line(data = curve_data, aes(xx, yy),
    color = "red",
    alpha = 0.7,
    linewidth = 2,
    show.legend = FALSE)

使用@Ben链接的 idea ,您可以通过提供修改后的数据来(错误地)使用geom_function,而不考虑geom_function的帮助:

data: Ignored by ‘stat_function()’, do not use.

您添加了几个geom_functions,其中刻面变量设置为各自的面板,如下所示:

gfs <- global_temp_quad |>
  group_by(month) |>
  group_map(~ geom_function(data = global_temps |> mutate(month = .y$month),
                   color = "red", alpha = .7, show.legend = FALSE, linewidth = 2,
                   fun = \(x) .x$intercept + .x$year * x + .x$year_2 * x ^ 2))

现在,gfs包含12个geom_functions,每个都具有不同的系数,并且数据时隙被覆盖,使得它仅适用于其各自的面板.您可以使用Reduce将它们添加到绘图p:

Reduce(`+`, gfs, p)

Facetted plot showing year on the x-axis and temperature on the y axis and a red smooth line for each panel

R相关问答推荐

如何将具有重复名称的收件箱合并到R中的另一列中,而结果不同?

如何从其他前面列中减go 特定列的平均值?

使用lapply的重新定位功能

根据shiny 应用程序中的数字输入更改图标 colored颜色

更改Heatmap Annotation对象的名称

从开始时间和结束时间导出时间

矩阵%*%矩阵中的错误:需要数字/复杂矩阵/向量参数

为什么横向页面会导致officeverse中的页码/节头/页脚出现问题?

在另一个函数中调用ggplot2美学

单个轮廓重叠条的单独图例

R根据条件进行累积更改

一小时满足条件的日期的 Select

在GG图中绘制射线的自动程序

基于数据集属性将科分配给物种

扩展R中包含列表的数据框

如何计算增加10米(0.01公里)的行?

网络抓取新闻标题和时间

使用列名和r中的前缀 Select 列的CREATE函数

将某个阈值以下的列中的值分类到不同的列中,否则保持该列的原样

如何在一种 colored颜色 中设置数值变量的 colored颜色 和高于阈值的 colored颜色 点?