How can I extract the values matrix of each density plot?
For example, I am interested in that when weight = 71, what will the density of orange, apple, pears, banana be ?
Below is the minimal example:
library(ggplot2)
set.seed(1234)
df = data.frame(
fruits = factor(rep(c("Orange", "Apple", "Pears", "Banana"), each = 200)),
weight = round(c(rnorm(200, mean = 55, sd=5),
rnorm(200, mean=65, sd=5),
rnorm(200, mean=70, sd=5),
rnorm(200, mean=75, sd=5)))
)
dim(df) [1] 800 2
ggplot(df, aes(x = weight)) +
geom_density() +
facet_grid(fruits ~ ., scales = "free", space = "free")
Save the plot in a variable, build the data structure with ggplot_build
and split the data by panel. Then interpolate with approx
to get the new values.
g <- ggplot(df, aes(x = weight)) +
geom_density() +
facet_grid(fruits ~ ., scales = "free", space = "free")
p <- ggplot_build(g)
# These are the columns of interest
p$data[[1]]$x
p$data[[1]]$density
p$data[[1]]$PANEL
Split the list member p$data[[1]]
by panel but keep only the x
and density
values. Then loop through the split data to interpolate by group of fruit.
sp <- split(p$data[[1]][c("x", "density")], p$data[[1]]$PANEL)
new_weight <- 71
sapply(sp, \(DF){
with(DF, approx(x, density, xout = new_weight))
})
# 1 2 3 4
#x 71 71 71 71
#y 0.04066888 0.05716947 0.001319164 0.07467761
Or, without splitting the data previously, use by
.
b <- by(p$data[[1]][c("x", "density")], p$data[[1]]$PANEL, \(DF){
with(DF, approx(x, density, xout = new_weight))
})
do.call(rbind, lapply(b, as.data.frame))
# x y
#1 71 0.040668880
#2 71 0.057169474
#3 71 0.001319164
#4 71 0.074677607