You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用ggplot2的geom_density绘制组内密度及组密度估计加权平均密度

Solution: Group Densities with Weighted Average of Density Estimates

Got it, let's walk through how to create exactly the plot you're asking for—group density curves plus a weighted average of those group-level density estimates (not the density of all combined data points). Here's a step-by-step implementation using tidyverse tools for clarity and flexibility:

Step 1: Load Packages and Generate Data

First, we'll load the tidyverse suite (for data manipulation and plotting) and generate your sample data with a seed set to ensure reproducibility:

library(tidyverse)

# Set seed for reproducible results
set.seed(123)

# Generate your data
x = c(rnorm(mean=0.0, n=100), rnorm(mean=1.0, n=100), rnorm(mean=2.0, n=200))
g = c(rep('a', 100), rep('b', 100), rep('c', 200))
d = data.frame(x=x, g=as.factor(g))

Step 2: Calculate Group Densities on a Unified Grid

To compute a meaningful average of density estimates, we first need to ensure all groups' densities are calculated over the same x-axis range and grid points. This way, we can align density values at identical x positions:

# Get the full range of x values across all groups
x_range = range(d$x)
# Create a unified grid of 1000 x points (adjustable)
x_grid = seq(x_range[1], x_range[2], length.out = 1000)

# Calculate density for each group and map to the unified grid
group_densities = d %>%
  group_by(g) %>%
  summarise(
    # Compute density for the group, spanning the full x range
    dens = list(density(x, from = x_range[1], to = x_range[2])),
    # Store group sample size for weighting
    n = n(),
    .groups = "drop"
  ) %>%
  # Interpolate density values to match our unified x grid
  mutate(dens_values = map(dens, ~ approx(.x$x, .x$y, xout = x_grid)$y)) %>%
  # Unnest into a long-format data frame for plotting
  unnest(cols = dens_values) %>%
  mutate(x = rep(x_grid, nrow(.)/length(x_grid)))

Step 3: Compute Weighted Average Density

We'll calculate the weighted average using group sample sizes as weights (since group c has twice as many observations as a or b). If you want an unweighted average instead, just replace n / total_n with 1 / n_distinct(g):

# Total number of observations
total_n = nrow(d)

# Calculate weighted average density at each x grid point
average_density = group_densities %>%
  group_by(x) %>%
  summarise(
    weighted_avg_dens = sum(dens_values * (n / total_n)),
    .groups = "drop"
  )

Step 4: Plot the Results

Finally, we'll use ggplot2 to layer the group density curves and the weighted average curve, styling it to match typical publication-ready plots:

ggplot() +
  # Plot group density curves (semi-transparent for clarity)
  geom_line(
    data = group_densities,
    aes(x = x, y = dens_values, color = g),
    alpha = 0.5,
    linewidth = 1
  ) +
  # Plot weighted average density (bold black dashed line)
  geom_line(
    data = average_density,
    aes(x = x, y = weighted_avg_dens),
    color = "black",
    linewidth = 1.2,
    linetype = "dashed"
  ) +
  # Add labels and title
  labs(
    x = "x",
    y = "Density",
    color = "Group",
    title = "Group Densities with Weighted Average of Density Estimates"
  ) +
  # Clean up the theme
  theme_minimal() +
  theme(
    plot.title = element_text(hjust = 0.5, size = 14, face = "bold"),
    legend.position = "top"
  )

Key Notes:

  • The unified x grid ensures we're averaging density values at the exact same x positions, which is critical for a valid average of density estimates.
  • You can tweak the plot styling (colors, line types, transparency) to match your target example—just adjust the arguments in geom_line() and theme().
  • For an unweighted average, swap the weighting term in average_density to 1 / n_distinct(g) (which would be 1/3 for your 3 groups).

内容的提问来源于stack exchange,提问作者adn bps

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.22 08:37:24