This is an R Markdown document. Markdown is a simple formatting syntax for authoring HTML, PDF, and MS Word documents. For more details on using R Markdown see http://rmarkdown.rstudio.com.
When you click the Knit button a document will be generated that includes both content as well as the output of any embedded R code chunks within the document. You can embed an R code chunk like this:
library(ggplot2)
# 1. Stat to compute the balance point
StatBalPoint <- ggproto("StatBalPoint", Stat,
required_aes = c("x", "y"),
compute_group = function(data, scales) {
# Convert x to numeric position (important for factors)
data$x_num <- as.numeric(factor(data$x, levels = unique(data$x)))
balance <- sum(data$x_num * data$y, na.rm = TRUE) / sum(data$y, na.rm = TRUE)
data.frame(x = balance, y = 0, label = "^")
}
)
# 2. Define geom_bal_point
geom_bal_point <- function(mapping = NULL, data = NULL,
stat = "bal_point", position = "identity",
..., na.rm = FALSE, show.legend = NA,
inherit.aes = TRUE) {
layer(
stat = StatBalPoint, geom = GeomText, mapping = mapping, data = data,
position = position, show.legend = show.legend,
inherit.aes = inherit.aes,
params = list(na.rm = na.rm, vjust = 1, ...) # vjust=1 puts tip at y = 0
)
}
You can also embed plots, for example:
Note that the echo = FALSE
parameter was added to the
code chunk to prevent printing of the R code that generated the
plot.
library(ggplot2)
# Step 1: Stat that calculates weighted average of x positions
StatBalPoint <- ggproto("StatBalPoint", Stat,
required_aes = c("x", "y"),
compute_panel = function(data, scales) {
# Map discrete x values to numeric positions (used for geom_col())
x_positions <- scales$x$map(data$x)
# Weighted mean x (balance point)
balance <- sum(x_positions * data$y, na.rm = TRUE) / sum(data$y, na.rm = TRUE)
data.frame(x = balance, y = 0, label = "^")
}
)
# Step 2: geom_bal_point() using GeomText with vertical alignment
geom_bal_point <- function(mapping = NULL, data = NULL,
stat = "bal_point", position = "identity",
..., na.rm = FALSE, show.legend = NA,
inherit.aes = TRUE) {
layer(
stat = StatBalPoint, geom = GeomText, mapping = mapping, data = data,
position = position, show.legend = show.legend, inherit.aes = inherit.aes,
params = list(na.rm = na.rm, vjust = 1, ...) # vjust = 1 aligns tip of "^" at y = 0
)
}
df <- data.frame(
category = c("A", "B", "C", "D"),
value = c(2, 6, 3, 1)
)
ggplot(df, aes(x = category, y = value)) +
geom_col() +
geom_bal_point(aes(x = category, y = value), size = 10, color = "red")