问题
This is a question that relates to my earlier question geom_smooth with facet_grid and different fitting functions. In that question, I was trying to use a different fitting function in geom_smooth
for each facet in a facet grid for ggplot2. Marco Sandri kindly provided an answer that I am trying to adapt to use user-defined formulas rather than existing formulas (e.g., lm
, loess
). Here is the my code.
# Load library
library(ggplot2)
# Load data
data(mtcars)
# Smoothing function with different behaviour depending on the panel
custom.smooth <- function(formula, data,...){
smooth.call <- match.call()
if(as.numeric(unique(data$PANEL)) == 6) {
# Nonlinear regression
method.name <- eval(parse(text="nls"))
# Specify formula
formula <- as.formula("y ~ a * x^b")
# Add initial parameters
smooth.call[["start"]] <- c(a = 10, b = -0.5)
}else{
# Linear regression
method.name <- eval(parse(text="lm"))
}
# Add function name
smooth.call[[1]] <- method.name
# Perform fit
eval.parent(smooth.call)
}
# Plot data with custom fitting function
p <- ggplot(mtcars,aes(x = disp, y = mpg)) + geom_point() + facet_grid(gear ~ am)
p <- p + geom_smooth(method = "custom.smooth")
print(p)
In this code, I define a function custom.smooth
that chooses the model to be fit. In this example, all models are linear regressions except for panel 6, which is a user-defined function y ~ a*x^b
. Running this code gives the error:
Warning message: Computation failed in
stat_smooth()
: singular gradient matrix at initial parameter estimates
Nevertheless, when I run nls
on the data in panel 6 with these initial parameters I get no such error (i.e., nls(mpg ~ a * disp^b, mtcars %>% filter(gear == 5, am == 1), start = c(a = 10, b = -0.5))
). This makes me think that nls
isn't seeing the start values I specify. I have also tried specifying these parameters in the geom_smooth
function like this:
p <- p + geom_smooth(method = "custom.smooth", method.args = list(start = c(a = 10, b = -0.5)))
but I run into the same issue. Any ideas how I can get my start values to nls
? Or is there another reason why the code isn't working?
回答1:
Here's the solution, which greatly benefited from this post. I don't know why the previous version didn't work, but this seems to work fine.
# Load library
library(ggplot2)
# Load data
data(mtcars)
# Smoothing function with different behaviour depending on the panel
custom.smooth <- function(formula, data,...){
smooth.call <- match.call()
if(as.numeric(unique(data$PANEL)) == 6) {
# Nonlinear regression
smooth.call[[1]] <- quote(nls)
# Specify formula
smooth.call$formula <- as.formula("y ~ a * x ^ b")
# Add initial parameters
smooth.call$start <- c(a = 300, b = -0.5)
}else{
# Linear regression
smooth.call[[1]] <- quote(lm)
}
# Perform fit
eval.parent(smooth.call)
}
# Plot data with custom fitting function
p <- ggplot(mtcars,aes(x = disp, y = mpg)) + geom_point() + facet_grid(gear ~ am)
p <- p + geom_smooth(method = "custom.smooth", se = FALSE)
print(p)
来源:https://stackoverflow.com/questions/44930704/r-nls-not-picking-up-additional-arguments-when-used-in-custom-function-in-geom