无法创建更平滑的曲线拟合图

时间:2017-03-12 16:34:14

标签: r

如何平滑拟合曲线?

XY <- data.frame(cbind(Values = c(91.8, 95.3,   99.8,   123.3,  202.9,  619.8,  1214.2, 1519.1, 1509.2, 1523.3, 1595.2, 1625.1),
            Concn = c(1000, 300,    100,    30, 10, 3,  1,  0.3,    0.1,    0.03,   0.01,   0)))
nls.fit <- nls(Values ~ (ymax* Concn / (ec50 + Concn)) + Ns*XY$Concn + ymin, data=XY,
                   start=list(ymax=max(XY$Values), ymin = min(XY$Values), ec50 = 3, Ns = 0.2045514))
plot(XY$Values ~ XY$Concn , data = XY, col = 4, main = "XY Std curve", log = "x")
lines(XY$Concn, predict(nls.fit))

当我尝试以下脚本时,我收到错误信息。

SmoothX <- seq(min(XY$Values), max(XY$Values), length = 100)
lines(SmoothX, predict(nls.fit,SmoothX), col='red', lwd=2)

错误(函数(公式,数据= NULL,subset = NULL,na.action = na.fail,:   变量长度不同(找到'SmoothX')

如何解决错误?

enter image description here

3 个答案:

答案 0 :(得分:2)

首先确保XY按Concn的升序排序,以确保当我们使用lines时,每个点都连接到下一个排序点而不是其他点。另外一定要从公式中删除XY,因为它已在data参数中指定,如果存在则会导致问题。使用plotlines参数subset,可以从plotlines中使用的数据中排除0,因为它们指定了对数刻度。

o <- order(XY$Concn)
XY <- XY[o, ]

fo <- Values ~ (ymax* Concn / (ec50 + Concn)) + Ns * Concn + ymin
st <- list(ymax=max(XY$Values), ymin = min(XY$Values), ec50 = 3, Ns = 0.2045514)
nls.fit <- nls(fo, data = XY, start = st)

plot(Values ~ Concn, XY, subset = Concn > 0, col = 4, log = "x")
title(main = "XY Std curve")
lines(predict(nls.fit, new = list(Concn = Concn)) ~ Concn, XY, subset = Concn > 0) ##

可选地,通过用以下3行代码替换lines语句(上面标记为##)可以使其更加平滑,以提供在对数刻度上等间隔的更多数量的点。请注意,我们在取对数之前删除0点。

logRange <- with(XY, log(range(Concn[Concn > 0])))
x <- exp(seq(logRange[1], logRange[2], length = 100))
lines(x, predict(nls.fit, new = list(Concn = x)))

省略标记为##的行,然后运行上面所有其余代码,包括我们得到的最后3行:

screenshot

答案 1 :(得分:1)

首先,我认为您在预测中使用的新数据应该使用浓度而不是值:

SmoothX <- seq(min(XY$Concn), max(XY$Concn), length = 100)

此外,看看SmoothX和predict(nls.fit,SmoothX)的长度不同:

str(SmoothX)

num [1:100] 91.8 107.3 122.8 138.3 153.8 ...

str(predict(nls.fit,SmoothX))

num [1:12] 109.5 49 52.3 120.6 298.6 ...

但是,如果你包含list(Concn=SmoothX),你将获得一个100个值的向量,因为你的新数据向量长度是。

 str(predict(nls.fit,list(Concn=SmoothX)))

num [1:100] 1714 324.7 175.5 119.6 91.8 ...

这样做效果更好,但它仍然会发出警告信息和一条难看的红线:c。

lines(SmoothX, predict(nls.fit,list(Concn=SmoothX)), col='red', lwd=2)

警告讯息: In(ymax * Concn /(ec50 + Concn))+ Ns * XY $ Concn:   较长的物体长度不是较短物体长度的倍数

Plot produced

答案 2 :(得分:1)

首先,您需要在nls()中使用不含XY$的公式:

nls.fit <- nls(Values ~ (ymax* Concn / (ec50 + Concn)) + 
                         Ns*Concn + ymin,
               data=XY,
               start=list(ymax=max(XY$Values), ymin = min(XY$Values),
                          ec50 = 3, Ns = 0.2045514))

简介:

plot(Values ~ Concn , data = XY, col = 4, main = "XY Std curve",
     log = "x")

如果您要在log-X比例上绘图,将有助于在日志比例上均匀地分布预测值。您还需要将预测数据作为具有相同变量名称(Conc)的数据框作为模型中的预测变量:

SmoothX <- with(XY,
      data.frame(Concn=10^seq(min(log10(Concn[Concn>0])),
                              max(log10(Concn)), length = 100)))
pp <- predict(nls.fit,SmoothX)
lines(SmoothX$Concn, pp, col='red', lwd=2)


 plot(Values ~ Concn , data = XY, col = 4, main = "XY Std curve",
     log = "x")
SmoothX <- with(XY,
      data.frame(Concn=10^seq(min(log10(Concn[Concn>0])),
                              max(log10(Concn)), length = 100)))
pp <- predict(nls.fit,SmoothX)
lines(SmoothX$Concn, pp, col='red', lwd=2)