【问题标题】:Using nls and ggplot2 to fit a logarithmic curve to data使用 nls 和 ggplot2 拟合数据的对数曲线
【发布时间】:2018-02-10 10:51:24
【问题描述】:

我正在使用 R 用方程拟合对数曲线上的数据:

y = a * log(b * x)

我的数据如下所示:

#Creating example data
pre <- c(946116, 1243227, 1259646, 1434124, 1575268, 2192526, 3252832, 6076519)  
post <- c(907355, 1553586, 1684253, 2592938, 1919173, 1702644,3173743, 3654198)  
data <- data.frame(pre,post)

#Plotting data
  ggplot(data, aes(x=pre, y=post))+
  geom_point()

但是,当我尝试使用 geom_smooth 拟合对数曲线时,出现错误。

# Fitting logarithmic curve
ggplot(data, aes(x=pre, y=post))+
  geom_point()+
  geom_smooth(method="nls", se=FALSE,
              method.args=list(formula=y~a*log(b*x),
                               start=c(a=100, b=2)))

警告信息:

1: In log(b * x) : NaNs produced
2: Computation failed in `stat_smooth()`:
Missing value or an infinity produced when evaluating the model 

当我尝试在 nls 中创建对数模型而不使用 ggplot 时,我遇到了类似的问题

model <- nls(data=data, 
             formula=y~a*log(b*x),
             start=list(a=100, b=2))

警告信息:

Error in numericDeriv(form[[3L]], names(ind), env) : 
  Missing value or an infinity produced when evaluating the model
In addition: Warning messages:
1: In min(x) : no non-missing arguments to min; returning Inf
2: In max(x) : no non-missing arguments to max; returning -Inf
3: In log(b * x) : NaNs produced

作为 R 新手,我不太明白错误消息试图告诉我什么。我知道我需要更改指定开始条件的方式,但我不知道如何。

【问题讨论】:

    标签: r modeling ggplot2 nls


    【解决方案1】:

    我在您的 nls 通话中发现了几个问题。 1) 当这些变量不存在时,您正在使用变量 xy。它们应该是 prepost。 2) 数字的大小给 nls 带来麻烦。将它们除以 1,000,000 会有所帮助。

    pre <- c(946116, 1243227, 1259646, 1434124, 1575268, 2192526, 3252832, 6076519)  
    post <- c(907355, 1553586, 1684253, 2592938, 1919173, 1702644,3173743, 3654198)
    
    pre = pre/1000000
    post = post/1000000
    
    data <- data.frame(pre,post)
    
    model <- nls(data=data, 
                 formula=post~a*log(b*pre),
                 start=list(a=1, b=1))
    
    summary(model)
    

    但如上一个答案所示,改变方程的形式会有所帮助,而无需改变数据的规模。

    pre <- c(946116, 1243227, 1259646, 1434124, 1575268, 2192526, 3252832, 6076519)  
    post <- c(907355, 1553586, 1684253, 2592938, 1919173, 1702644,3173743, 3654198)
    
    data <- data.frame(pre,post)
    
    model <- nls(data=data, 
                 formula=post~a*log(pre)+b,
                 start=list(a=1, b=0))
    
    summary(model)
    

    【讨论】:

      【解决方案2】:

      试试这个:

      ggplot(data, aes(x=pre, y=post))+
        geom_point()+
        geom_smooth(method="nls", se=FALSE, formula=y~a*log(x)+k,
                    method.args=list(start=c(a=1, k=1)))
      

      请注意,它本质上是相同的公式,但现在是k = a * log(b)

      a * log(b * x) = a * {log(b) + log(x)} = a * log(x) + a * log(b) = a * log(x) + k

      【讨论】:

        猜你喜欢
        • 2016-02-02
        • 2018-06-04
        • 1970-01-01
        • 1970-01-01
        • 2016-09-20
        • 1970-01-01
        • 2011-05-21
        • 2017-08-04
        • 2011-01-15
        相关资源
        最近更新 更多