R:在 geom_smooth 中的自定义函数中使用时,nls 不获取其他参数
R: nls not picking up additional arguments when used in custom function in geom_smooth
这是一个与我之前的问题相关的问题 . 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 友情地提供了一个答案,我正在努力调整以使用用户定义的公式而不是现有的公式(例如,lm
、loess
).这是我的代码。
# 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)
在这段代码中,我定义了一个函数 custom.smooth
来选择要拟合的模型。在此示例中,所有模型都是线性回归,但面板 6 除外,面板 6 是用户定义的函数 y ~ a*x^b
。 运行 此代码给出错误:
Warning message: Computation failed in stat_smooth()
: singular
gradient matrix at initial parameter estimates
然而,当我使用这些初始参数 运行 nls
面板 6 中的数据时,我没有得到这样的错误(即 nls(mpg ~ a * disp^b, mtcars %>% filter(gear == 5, am == 1), start = c(a = 10, b = -0.5))
)。这让我觉得 nls
没有看到我指定的起始值。我也试过在 geom_smooth
函数中指定这些参数,如下所示:
p <- p + geom_smooth(method = "custom.smooth", method.args = list(start = c(a = 10, b = -0.5)))
但我 运行 遇到了同样的问题。有什么想法可以让我的起始值达到 nls
吗?或者还有其他原因导致代码无法正常工作?
这是解决方案,受益于this post。我不知道为什么以前的版本不能用,但这似乎很好用。
# 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)
这是一个与我之前的问题相关的问题 geom_smooth
for each facet in a facet grid for ggplot2. Marco Sandri 友情地提供了一个答案,我正在努力调整以使用用户定义的公式而不是现有的公式(例如,lm
、loess
).这是我的代码。
# 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)
在这段代码中,我定义了一个函数 custom.smooth
来选择要拟合的模型。在此示例中,所有模型都是线性回归,但面板 6 除外,面板 6 是用户定义的函数 y ~ a*x^b
。 运行 此代码给出错误:
Warning message: Computation failed in
stat_smooth()
: singular gradient matrix at initial parameter estimates
然而,当我使用这些初始参数 运行 nls
面板 6 中的数据时,我没有得到这样的错误(即 nls(mpg ~ a * disp^b, mtcars %>% filter(gear == 5, am == 1), start = c(a = 10, b = -0.5))
)。这让我觉得 nls
没有看到我指定的起始值。我也试过在 geom_smooth
函数中指定这些参数,如下所示:
p <- p + geom_smooth(method = "custom.smooth", method.args = list(start = c(a = 10, b = -0.5)))
但我 运行 遇到了同样的问题。有什么想法可以让我的起始值达到 nls
吗?或者还有其他原因导致代码无法正常工作?
这是解决方案,受益于this post。我不知道为什么以前的版本不能用,但这似乎很好用。
# 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)