【问题标题】:Extracting x-axis intercept from a linear fit in R从 R 中的线性拟合中提取 x 轴截距
【发布时间】:2014-05-24 02:30:23
【问题描述】:

我有一些使用以下代码行生成的数据,

x <- c(1:10)
y <- x^3
z <- y-20
s <- z/3
t <- s*6
q <- s*y
x1 <- cbind(x,y,z,s,t,q)
x1 <- data.frame(x1)

我想绘制 x 与 y、s 和 t 的关系图,所以我先将数据框 x1 融化,

 library(reshape2)

 xm <- melt(x1, id=names(x1)[1], measure=names(x1)[c(2, 4, 5)], variable = "cols"`)

然后我使用以下代码将它们与线性拟合一起绘制,

library(ggplot2)
plt <- ggplot(xm, aes(x = x, y = value, color = cols)) +
  geom_point(size = 3) +
  labs(x = "x", y = "y") + 
  geom_smooth(method = "lm", se = FALSE)
plt

生成的图如下所示,

现在我想插入线性拟合的 x 截距。图中 y 轴值为 0 的点。

如下代码行如here所示,提取斜率和y截距。

fits <- by(xm[-2], xm$cols, function(i) coef(lm(value ~ x, i)))
data.frame(cols = names(fits), do.call(rbind, fits))

除了从斜率和 y 截距手动计算之外,还有什么方法可以提取 x 截距?

感谢您的帮助!

【问题讨论】:

    标签: r ggplot2 lm intercept


    【解决方案1】:

    我认为您无法避免计算线性方程,但您当然不必手动完成(除非您愿意)。例如:

    by(xm[-2], xm$cols, function(i) { 
    fit <- lm(value~x, i); print(fit); solve(coef(fit)[-1], -coef(fit)[1] )}
    )
    
    Call:
    lm(formula = value ~ x, data = i)
    
    Coefficients:
    (Intercept)            x  
         -277.2        105.4  
    
    
    Call:
    lm(formula = value ~ x, data = i)
    
    Coefficients:
    (Intercept)            x  
         -99.07        35.13  
    
    
    Call:
    lm(formula = value ~ x, data = i)
    
    Coefficients:
    (Intercept)            x  
         -594.4        210.8  
    
    xm$cols: y
    [1] 2.629981
    ----------------------------------------------------------------------------------------------------------------- 
    xm$cols: s
    [1] 2.819734
    ----------------------------------------------------------------------------------------------------------------- 
    xm$cols: t
    [1] 2.819734
    

    解决的问题基本上是 -277.2 + 105.4*x = 0 for x -> 105.4*x = 277.2(求解函数调用)-> x = 2.629981。似乎您的线“s”和“t”在同一点与 y=0 轴相交。如果我理解正确,您的问题不是外推,因为您的 x 范围涵盖了截距,而是插值。

    附言。我认为您的代码丢失了:require("reshape")

    编辑:

    result <- c(by(xm[-2], xm$cols, function(i) { fit <- lm(value~x, i); print(fit); solve(coef(fit)[-1], -coef(fit)[1] )} )); print(result) 
    > print(result)
           y        s        t 
    2.629981 2.819734 2.819734 
    

    【讨论】:

    • 感谢您的建议。我现在还找到了另一种解决此问题的方法。我现在编辑了我的代码以包含 reshape 包。
    • 有没有办法将 x-intercept 的值传递给生成的结果列表中的数据框。
    • 我不完全确定您的意思...您的意思是如何访问求解器返回的原始值?你可以做例如: 结果
    • 我想以下面我的答案中指示的格式在单列中获得结果。
    • 好的,我编辑了我的答案以显示这一点。根据我的回答,它给出了一个行向量,但您可以执行“t(result)”来获得与您的列向量相同的列向量。
    【解决方案2】:

    我找到了一种计算 x 截距的方法,首先用 y 截距和斜率值创建一个数据框,

    par <- data.frame(cols = names(fits), do.call(rbind, fits))
    

    然后重命名列标题名称以准确表示值,

    colnames(par)[2] <- "y_intercept"
    colnames(par)[3] <- "slope"
    # Calculate the x-intercept by using the formula -(y_intercept)/slope
    x_incpt <- -par[2]/par[3]
    colnames(x_incpt) <- "x_intercept"
    

    结果如下,

      x_intercept
    y    2.629981
    s    2.819734
    t    2.819734
    

    【讨论】:

      【解决方案3】:

      如果您不想自己计算,可以按照在 chemCal 包中实现的逆向预测进行校准:

      library(chemCal)
      res <- by(xm[-2], xm$cols, function(i) inverse.predict(lm(value ~ x, i), 0)$Prediction)
      res[1:3]
      #xm$cols
      #y        s        t 
      #2.629981 2.819734 2.819734
      

      编辑:

      也许你更喜欢这个:

      library(plyr)
      res <- ddply(xm, .(cols), 
        function(i) data.frame(xinter=inverse.predict(lm(value ~ x, i), 0)$Prediction))
      #   cols   xinter
      # 1    y 2.629981
      # 2    s 2.819734
      # 3    t 2.819734
      

      【讨论】:

      • 感谢您的建议。我想将结果作为单列获得,所以我使用 t(res[1:3]) 这不起作用。在这种情况下,只有 3 次拟合,所以我们给索引 1:3,但是如果有 n 次拟合怎么办,其中不知道 n 的值.
      • 谢谢,这正是我需要的。
      猜你喜欢
      • 2020-10-28
      • 2018-01-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多