在 R 中绘制多个子图的曲线

Plotting curve over several subplots in R

我有一个包含 50k 行和 6 列的数据框 df。现在我在 6 个子图中绘制了所有 6 列,这要归功于我可以在这里找到的解决方案:

library(ggplot2)
library(tidyr)

ggplot(gather(df, cols, value), aes(x = value)) + 
      geom_histogram(binwidth = 0.25) + 
      facet_wrap(.~cols)

背景:对于所有数据列,我都绘制了 0 到 10 之间的随机数。对于每一列,我都绘制了更多数字并计算了平均值。当我这样做 50k 次并在直方图上绘制数字时。第一个情节几乎是平淡无奇的,最后一个情节看起来像摩天大楼。

现在我当然找到了几个如何向直方图添加一条曲线的例子,但这些都没有子图,所以我无法让它工作。我的新代码 (source):

ggplot(gather(df, cols, value), aes(x = value)) + 
      geom_histogram(binwidth = 0.25) + 
      stat_function(fun = dnorm, args = list(mean = mean(df$n1), sd = sd(df$n1))) +
      facet_wrap(.~cols)

如您所见,我尝试从我的第一个数据列中获取均值和标准差(它们被命名为 n1、n2、n3、n10、n100、n1000,代表绘图的数量)。所以我的问题是:

  1. 该代码暂时不起作用,因为每个子图中的曲线都为零。我做错了什么?
  2. 如何为每个子图使用不同的方法和 sd?

感谢您的帮助!

编辑:

我的 df 是这样生成的:

ROWS = 50000
MIN = 0
MAX = 10


df = data.frame(n1 = replicate(ROWS, mean(runif(n = 1, min = MIN, max = MAX))))
df$n2 = replicate(ROWS, mean(runif(n = 2, min = MIN, max = MAX)))
df$n3 = replicate(ROWS, mean(runif(n = 3, min = MIN, max = MAX)))
df$n10 = replicate(ROWS, mean(runif(n = 10, min = MIN, max = MAX)))
df$n100 = replicate(ROWS, mean(runif(n = 100, min = MIN, max = MAX)))
df$n1000 = replicate(ROWS, mean(runif(n = 1000, min = MIN, max = MAX)))
  1. 代码运行正常,但直方图和密度尺度不同。我的意思是,直方图适用于您的数据规模,但密度适用于概率。因此,您需要使用 geom_histogram(aes(y = ..density..)).

  2. 使用不同的方法和 sds 对我来说是一个棘手的问题。我阅读 并想出了这个主意(免责声明: 需要几秒钟才能 运行):

Edit. 我忘记在我自己的 geom 中使用的数据框中包含一个 name 列,这是 facet 部分的关键。此外,我现在使用您的数据并将名称列定义为因素,以便正确排序。

library(tidyverse)

ROWS = 50000
MIN = 0
MAX = 10

df = data.frame(n1 = replicate(ROWS, mean(runif(n = 1, min = MIN, max = MAX))))
df$n2 = replicate(ROWS, mean(runif(n = 2, min = MIN, max = MAX)))
df$n3 = replicate(ROWS, mean(runif(n = 3, min = MIN, max = MAX)))
df$n10 = replicate(ROWS, mean(runif(n = 10, min = MIN, max = MAX)))
df$n100 = replicate(ROWS, mean(runif(n = 100, min = MIN, max = MAX)))
df$n1000 = replicate(ROWS, mean(runif(n = 1000, min = MIN, max = MAX)))

df_pivot <- df %>% 
  pivot_longer(everything()) %>% 
  mutate(name = forcats::as_factor(name)) %>% 
  group_by(name) %>% 
  mutate(mean = mean(value), 
         sd = sd(value)) %>% 
  ungroup()

my_geom <- function(yy, dt = df_pivot){
  geom_line(aes(y = yy), 
            color = "red",
            data = tibble(value = dt$value, 
                          yy = yy, 
                          name = dt$name))
}

ggplot(df_pivot, aes(x = value)) + 
  geom_histogram(aes(y = ..density..), binwidth = 0.25) +
  my_geom(dnorm(df_pivot$value, mean = df_pivot$mean, sd = df_pivot$sd)) +
  facet_wrap(. ~ name, scales = "free_y")