I have a dataframe like this ->
df = data.frame(c("LALO","LALO", "AMGP", "AMGP", "WRSA", "WRSA", "SNOW", "SNOW"),
c(4.3, 2.5, 1.5, 1.2, 0.4, 0.2, 0.1, 0.05))
colnames(df) = c("sp_code","ind_km2")
df <- mutate(df, sp_code = factor(sp_code))
# df table :
sp_code ind_km2
1 LALO 4.30
2 LALO 2.50
3 AMGP 1.50
4 AMGP 1.20
5 WRSA 0.40
6 WRSA 0.20
7 SNOW 0.10
8 SNOW 0.05
I am using a loop to plot ind_km2 for each species :
sp_code <- levels(unique(df$sp_code))
for (i in seq_along(sp_code)) {
species <- sp_code[i]
plot2 <- df %>%
ggplot(aes(x=sp_code, y=ind_km2, fill=sp_code)) +
geom_violin(data = filter(df, sp_code == species), scale = "width", show.legend = FALSE) +
stat_summary(data = filter(df, sp_code == species), fun.y=mean, geom="point", shape=23, size=4, fill = "black", show.legend = FALSE)
print(plot2)
}
I want to add the number of observations for each plot. I've searched online for solutions, but they either gave me errors or the filter is not working correctly.
I've tried using stat_summary with a function :
# Function
add_n <- function(y, upper_limit = (df %>%
select(sp_code, ind_km2) %>%
filter(sp_code == species) %>%
summarise(mean = mean(ind_km2))) * 1.15) {
return(
data.frame(
y = 0.95 * upper_limit,
label = paste('n =', length(df), '\n')
)
)
}
# Add it to loop
for (i in seq_along(sp_code)) {
species <- sp_code[i]
plot2 <- df %>%
ggplot(aes(x=sp_code, y=ind_km2, fill=sp_code)) +
geom_violin(data = filter(df, sp_code == species), scale = "width", show.legend = FALSE) +
stat_summary(data = filter(df, sp_code == species), fun.y=mean, geom="point", shape=23, size=4, fill = "black", show.legend = FALSE)+
stat_summary(
fun.data = add_n,
geom = "text",
fun.y = median,
hjust = 0.5,
vjust = 0.9)
print(plot2)
}
This gave me an error (geom_text()` requires the following missing aesthetics: y), which I tried to fix with while looking online but couldn't find a solution that worked for me.
How can I either fix this error, or either use something else to have the number of observations for each level in my plots ?
(Thank you !)
I have a dataframe like this ->
df = data.frame(c("LALO","LALO", "AMGP", "AMGP", "WRSA", "WRSA", "SNOW", "SNOW"),
c(4.3, 2.5, 1.5, 1.2, 0.4, 0.2, 0.1, 0.05))
colnames(df) = c("sp_code","ind_km2")
df <- mutate(df, sp_code = factor(sp_code))
# df table :
sp_code ind_km2
1 LALO 4.30
2 LALO 2.50
3 AMGP 1.50
4 AMGP 1.20
5 WRSA 0.40
6 WRSA 0.20
7 SNOW 0.10
8 SNOW 0.05
I am using a loop to plot ind_km2 for each species :
sp_code <- levels(unique(df$sp_code))
for (i in seq_along(sp_code)) {
species <- sp_code[i]
plot2 <- df %>%
ggplot(aes(x=sp_code, y=ind_km2, fill=sp_code)) +
geom_violin(data = filter(df, sp_code == species), scale = "width", show.legend = FALSE) +
stat_summary(data = filter(df, sp_code == species), fun.y=mean, geom="point", shape=23, size=4, fill = "black", show.legend = FALSE)
print(plot2)
}
I want to add the number of observations for each plot. I've searched online for solutions, but they either gave me errors or the filter is not working correctly.
I've tried using stat_summary with a function :
# Function
add_n <- function(y, upper_limit = (df %>%
select(sp_code, ind_km2) %>%
filter(sp_code == species) %>%
summarise(mean = mean(ind_km2))) * 1.15) {
return(
data.frame(
y = 0.95 * upper_limit,
label = paste('n =', length(df), '\n')
)
)
}
# Add it to loop
for (i in seq_along(sp_code)) {
species <- sp_code[i]
plot2 <- df %>%
ggplot(aes(x=sp_code, y=ind_km2, fill=sp_code)) +
geom_violin(data = filter(df, sp_code == species), scale = "width", show.legend = FALSE) +
stat_summary(data = filter(df, sp_code == species), fun.y=mean, geom="point", shape=23, size=4, fill = "black", show.legend = FALSE)+
stat_summary(
fun.data = add_n,
geom = "text",
fun.y = median,
hjust = 0.5,
vjust = 0.9)
print(plot2)
}
This gave me an error (geom_text()` requires the following missing aesthetics: y), which I tried to fix with while looking online but couldn't find a solution that worked for me.
How can I either fix this error, or either use something else to have the number of observations for each level in my plots ?
(Thank you !)
Share Improve this question asked Feb 16 at 15:30 MagMag 315 bronze badges1 Answer
Reset to default 2I want to add the number of observations for each plot.
Adapted data (added another observation for "LALO"
) and moved factor()
inside data.frame()
.
df0 = data.frame(sp_code = factor(c("LALO","LALO", "AMGP", "AMGP", "WRSA", "WRSA", "SNOW", "SNOW", "LALO")),
ind_km2 = c(4.3, 2.5, 1.5, 1.2, 0.4, 0.2, 0.1, 0.05, 1.7))
(1) You could use count
in ggplot2::geom_text()
. Avertising ggplot2::facet_wrap()
.
library(ggplot2)
df0 |>
ggplot(aes(x = sp_code, y = ind_km2, fill = sp_code)) +
geom_violin() +
facet_wrap(~sp_code, scales = 'free') +
geom_text(aes(x = stage(sp_code, after_stat = Inf),
y = after_stat(Inf),
label = after_stat(sprintf('n=%s', count))),
stat = 'count', hjust = 1, vjust = 1)
(2) If you really want a plot for each level of sp_code
, what should we do with the colour filling?
l = split(df0, ~sp_code)
n = length(l)
col = palette.colors(n, palette = 'Set 1')
lapply(seq(n), \(i) {
l[[i]] |>
ggplot(ggplot2::aes(x = sp_code, y = ind_km2)) +
geom_violin(fill = col[i]) +
geom_text(aes(x = stage(sp_code, after_stat = Inf),
y = after_stat(Inf),
label = after_stat(sprintf('n=%s', count))),
stat = 'count', hjust = 1, vjust = 1)
})