In the following reproducible example I'm attempting to build a ggplot2
function call dynamically, in order to be able to accommodate unknown number of mixture distribution components. The code produces this error message: Error in parse(text = g) : <text>:8:0: unexpected end of input
. What is the problem with the code? (I'm aware of the method of pre-calculating plot data, storing it in a data frame, melting it and supplying it to ggplot2
. I would like to explore the option below, as well.) Thank you!
library(ggplot2)
library(scales)
library(RColorBrewer)
library(mixtools)
NUM_COMPONENTS <- 2
set.seed(12345) # for reproducibility
data(diamonds, package='ggplot2') # use built-in data
myData <- diamonds$price
calc.component <- function(x, lambda, mu, sigma) {
lambda * dnorm(x, mean = mu, sd = sigma)
}
overlayHistDensity <- function(data, func) {
# extract 'k' components from mixed distribution 'data'
mix <- normalmixEM(data, k = NUM_COMPONENTS,
maxit = 100, epsilon = 0.01)
summary(mix)
DISTRIB_COLORS <-
suppressWarnings(brewer.pal(NUM_COMPONENTS, "Set1"))
# plot histogram, empirical and fitted densities
g <- "ggplot(data) +\n"
for (i in seq(length(mix$lambda))) {
args <- paste0("args.", i)
assign(args, list(lambda = mix$lambda[i], mu = mix$mu[i],
sigma = mix$sigma[i]))
g <- paste0(g,
"stat_function(fun = func, args = ",
args,
", aes(color = ",
DISTRIB_COLORS[i], ")) +\n")
}
tailStr <-
"geom_line(aes(y = ..density..,colour = 'Empirical'),stat = 'density') +
geom_histogram(aes(y = ..density..), alpha = 0.4) +
scale_colour_manual(name = '', values = c('red', 'blue')) +
theme(legend.position = 'top', legend.direction = 'horizontal')"
g <- paste0(g, tailStr)
gr <- eval(parse(text = g))
return (gr)
}
overlayHistDensity(log10(myData), 'calc.component')