我正在使用一台仪器测量许多不同的化合物,每种化合物都有不同的校准曲线。我想根据化合物的名称将正确的校准曲线应用于原始数据到仪器的原始数据。因此,我从多个校准曲线和原始数据的数据框开始:
#generate the calibration curves
x <- 1:10
calib.data.1 <- x+runif(10)
lm.1 <- lm(calib.data.1~x)
calib.data.2 <- 2*x+runif(10)
lm.2 <- lm(calib.data.2~x)
原始数据如下所示:
compound <- factor(c("cpd1", "cpd2"))
values <- runif(2)
raw <- data.frame(compound, values)
选择正确校准曲线的优雅方式似乎涉及ddply或类似。但是,如果不按以下方式编写函数,我无法弄清楚如何做到这一点:
choose.calib <- function(raw, cpd)
if(cpd=="cpd1"){
calib=coef(lm.1)[1]+val*coef(lm.2)[2]
}else{
if(cpd=="cpd2"){
calib=coef(lm.2)[1]+val*coef(lm.2)[2]
}else{
warning("no calib curve for compound")}}
}
然后我会做类似
的事情cal<-ddply(raw, .(compound), choose.calib)
(由于我无法理解if-else,这无论如何都行不通;但我想我可以自己解决这个问题)
有更多的矢量化方法吗?
答案 0 :(得分:3)
向我跳出来的一种方法是创建一个包含几个字段的系数data.frame,如[cpd,intercept,coef]
然后,您可以使用merge()
将系数data.frame“加入”到起始data.frame,然后在相同的数据帧中得到校准系数。
以下是使用您的数据的简单示例:
x <- 1:10
calib.data.1 <- x+runif(10)
lm.1 <- lm(calib.data.1~x)
lm1coef <- data.frame(compound="cpd1", t(lm.1$coefficients))
names(lm1coef) <- c("compound","intercept","b1")
calib.data.2 <- 2*x+runif(10)
lm.2 <- lm(calib.data.2~x)
lm2coef <- data.frame(compound="cpd2",t(lm.2$coefficients))
names(lm2coef) <- c("compound","intercept","b1")
coefs <- rbind(lm1coef, lm2coef)
compound <- factor(c("cpd1", "cpd2"))
values <- runif(2)
raw <- data.frame(compound, values)
raw2 <- merge(raw, coefs)
显然,您可以将提取系数的位转换为函数。但这给了你一个要点。
答案 1 :(得分:1)
或者,您可以创建一个包含模型的list
对象,并按其复合类型编制索引。例如。这样的事情应该有效:
calibList <- list()
calibList$cpd1 <- lm.1
calibList$cpd2 <- lm.2
choose.calib <- function(cpd, calibList){ return(calibList[[cpd]]) }
predict.calib <- function(raw, cpd, calibList){
predict(choose.calib(cpd, calibList), raw)
}
ddply(raw, predict.calib, cpd, calibList)
最好知道predict.lm()
函数,这样就不需要提取系数来“手动”进行预测。