r - 使用 ggplot2 绘制多条正态曲线,无需硬编码均值和标准差

标签 r ggplot2 dplyr normal-distribution mapply

我有一个均值和标准差向量,我想使用 ggplot2 在同一图中绘制与这些均值和标准差相对应的密度。我使用 mapplygather 来解决这个问题,但是对于我认为应该微不足道的事情来说,这是相当多的代码行:

library(dplyr)
library(tidyr)
library(ggplot2)

# generate data
my_data <- data.frame(mean =  c(0.032, 0.04, 0.038, 0.113, 0.105, 0.111),
                      stdev = c(0.009, 0.01, 0.01, 0.005, 0.014, 0.006), 
                      test = factor(c("Case_01", "Case_02", "Case_03", "Case_04",
                                      "Case_05", "Case_06")))

# points at which to evaluate the Gaussian densities
x <- seq(-0.05, 0.2, by = 0.001)

# build list of Gaussian density vectors based on means and standard deviations
pdfs <- mapply(dnorm, mean = my_data$mean, sd = my_data$stdev, MoreArgs = list(x = x),
               SIMPLIFY = FALSE)

# add group names
names(pdfs) <- my_data$test

# convert list to dataframe
pdfs <- do.call(cbind.data.frame, pdfs)
pdfs$x <- x

# convert dataframe to tall format
tall_df <- gather(pdfs, test, density, -x)

# build plot
p <- ggplot(tall_df, aes(color = test, x = x, y = density)) +
  geom_line() +
  geom_segment(data = my_data, aes(color = test, x = mean, y = 0, 
                                   xend = mean, yend = 100), linetype = "dashed") +
  coord_cartesian(ylim = c(-1, 100))
print(p)

enter image description here这非常类似于:

Plot multiple normal curves in same plot

事实上,the accepted answer使用 mapply,这让我确信我走在正确的轨道上。然而,我不喜欢这个答案的是它在 mapply 调用中硬编码了平均值和标准差。这在我的用例中不起作用,因为我从磁盘读取真实数据(当然,在 MRE 中,为了简单起见,我跳过了数据读取部分)。是否可以简化我的代码,而不牺牲可读性,并且无需在 mapply 调用中对平均值和标准差向量进行硬编码?

编辑也许可以通过使用包mvtnorm来避免对maply的调用,但我认为这并不能提供任何真正的简化这里。我的大部分代码都在调用 mapply 之后出现。

最佳答案

您可以使用 purrr::pmap_df 保存一些编码,在为每个 mean-stdev 构建数据框后自动进行行绑定(bind)。对:

假设 my_data输入列的顺序为 mean, stdev, testtest属于字符类。

library(purrr)
tall_df2 <- pmap_df(my_data, ~ data_frame(x = x, test = ..3, density = dnorm(x, ..1, ..2)))

有数据:

my_data <- data.frame(mean =  c(0.032, 0.04, 0.038, 0.113, 0.105, 0.111),
                      stdev = c(0.009, 0.01, 0.01, 0.005, 0.014, 0.006), 
                      test = c("Case_01", "Case_02", "Case_03", "Case_04", "Case_05", "Case_06"), 
                      stringsAsFactors = F)

剧情:

p <- ggplot(tall_df2, aes(color = factor(test), x = x, y = density)) + 
      geom_line() +
      geom_segment(data = my_data, aes(color = test, x = mean, y = 0, 
                                       xend = mean, yend = 100), linetype = "dashed") +
      coord_cartesian(ylim = c(-1, 100))

print(p)

给出:

enter image description here

关于r - 使用 ggplot2 绘制多条正态曲线,无需硬编码均值和标准差,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47204418/

相关文章:

r - 在 R 中使用 Leaflet 时如何在 addCircleMarkers() 中指定半径单位

r - 使 geom_text 颜色比 geom_point 颜色深

r - 错误ggplot(seq.int(0,to0 - from,by)错误): 'to' must be finite)

r - 在 R 中仅按组保存最后一个重复项

r - tidyr `fill()` 可以与 R 中的 if_else() 一起使用吗?

html - 将文本定位在 R shiny 中的 Action Button 中

R Highcharter 在使用 hc_yAxis_multiples 的 y 轴上添加绘图带时出现的问题

r - ggplot2 geom_bar position = "dodge"不闪避

r - data.table 相当于 dplyr::filter_at

r - 列式计算