I want to plot a density histogram in R with discrete data. Given that my dataset is very large I need to compute the densities prior plotting.
However, I find that using the stats::density function provides different results compared to ..density.. in ggplot2. Why is that? Also the ..density.. results from ggplot2 are in line with what is expected whereas stats::density are not.
See reproducible example below.
Many Thanks
library(tidyverse)
library(patchwork)
df <- data.frame(A = round(rnorm(1000)),
B = round(rnorm(1000)),
C = round(rnorm(1000))) %>%
pivot_longer(cols = everything(), names_to = "group")
dens_df <- df %>%
group_by(group) %>%
summarise(dens = list(density(value, from = -3, to = 6, n = length(-3:6)))) %>% #compute density and nest into list
mutate(density.x = map(dens, ~.x[["x"]]), #extract x values
density.y = map(dens, ~.x[["y"]])) %>% #extract y values
select(-dens) %>%
unnest(cols = c(density.x, density.y))
plot_dens <- dens_df %>%
ggplot()+
aes(x = density.x, y = density.y) %>%
geom_col()+
scale_x_continuous(breaks = seq(-3,10,1))+
stat_function(fun = dnorm, n = 10, args = list(mean = 0, sd = 1), geom = "point", col = "red") +
stat_function(fun = dnorm, n = 10, args = list(mean = 0, sd = 1), geom = "point", size = 2, col = "red") +
stat_function(fun = dnorm, n = 10, args = list(mean = 0, sd = 1), geom = "line", col = "red") +
facet_wrap(~group)+
labs(title = "using stats::density")
plot_geom <- df %>%
ggplot()+
aes(x = value, y = ..density..) %>%
geom_histogram(
binwidth = 1,
col = "white")+
scale_x_continuous(breaks = seq(-3,10,1))+
stat_function(fun = dnorm, n = 10, args = list(mean = 0, sd = 1), geom = "point", col = "red") +
stat_function(fun = dnorm, n = 10, args = list(mean = 0, sd = 1), geom = "point", size = 2, col = "red") +
stat_function(fun = dnorm, n = 10, args = list(mean = 0, sd = 1), geom = "line", col = "red") +
facet_wrap(~group)+
labs(title = "using ggplot2 ..density..")
plot_dens + plot_geom
