如何平滑拟合曲线?
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')
如何解决错误?
答案 0 :(得分:2)
首先确保XY按Concn
的升序排序,以确保当我们使用lines
时,每个点都连接到下一个排序点而不是其他点。另外一定要从公式中删除XY
,因为它已在data
参数中指定,如果存在则会导致问题。使用plot
和lines
参数subset
,可以从plot
和lines
中使用的数据中排除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行:
答案 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: 较长的物体长度不是较短物体长度的倍数
答案 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)