在ggplot2中的nls和log scale

时间:2014-07-27 17:40:34

标签: r ggplot2 nls

我试图在ggplot2中绘制3个非线性模型。 它以自动比例工作,但不是log10比例,我得到了#34;奇异梯度误差"。可能是什么问题?

我试图拟合的数据(df1):

x   y
4.17    0.55
10.08   0.48
40.25   0.38
101.17  0.32
400.33  0.24

我试过的代码:

plot <- ggplot(df1, aes(x=x, y=y))+
  stat_smooth(method="nls",
              formula=y~I(a*x^(-n)),
              data=df1,
              start=list(a=1,n=1),
              se=FALSE,
              colour="red")+
  stat_smooth(method="nls",
              formula=y~m*(x+m^(1/n))^(-n),
              data=df1,
              start=list(m=0.7, n=0.17),
              se=FALSE,
              colour="blue")+
  stat_smooth(method="nls",
              formula=y~m*(x+m^(1/n))^(-n)+b,
              data=df1,
              start=list(m=0.7, n=0.17, b=1),
              se=FALSE,
              colour="green")+
  geom_point()+
  scale_x_log10()+
  scale_y_log10()+
  theme_bw()
plot

1 个答案:

答案 0 :(得分:3)

问题似乎是,当您指定scale_x_log10scale_y_log10时,数据的值会在传递到不同的统计信息或地理位置之前进行转换。这意味着虽然您的nls可以处理未转换的数据,但它不适用于对数转换后的数据。

#OK
nls(y~m*(x+m^(1/n))^(-n), df1, start=list(m=0.7, n=0.17))
#NOT OK
nls(y~m*(x+m^(1/n))^(-n), log10(df1), start=list(m=0.7, n=0.17))

ggplot2中你似乎无法解决这个问题。相反,您可以提前在未转换的比例上拟合NLS模型,并使用ggplot2绘制结果。例如

mods<-list(
    list(y~I(a*x^(-n)), list(a=1,n=1)),
    list(y~m*(x+m^(1/n))^(-n), list(m=0.7, n=0.17)),
    list(y~m*(x+m^(1/n))^(-n)+b, list(m=0.7, n=0.17, b=1))
)

fits<-lapply(mods, function(x, xr) {
    mod<-nls(x[[1]], data=df1, start=x[[2]])
    xx<-seq(xr[1], xr[2], length.out=100)
    yy<-predict(mod, newdata=data.frame(x=xx))
    data.frame(x=xx, y=yy)
}, xr=range(df1$x))

library(ggplot2)
ggplot(df1, aes(x=x, y=y))+
  geom_line(data=fits[[1]], color="red") +
  geom_line(data=fits[[2]], color="blue") +
  geom_line(data=fits[[3]], color="green") +
  geom_point()+
  scale_x_log10()+
  scale_y_log10()+
  theme_bw()

将产生

enter image description here