Как элегантно выбрать и применить функцию калибровки, возможно, используя ddply? - PullRequest
4 голосов
/ 02 ноября 2011

Я измеряю множество различных химических соединений, каждое из которых имеет свою калибровочную кривую, используя один прибор.Я хотел бы применить правильную калибровочную кривую, основанную на названии соединения, к необработанным данным к необработанным данным с прибора.Итак, я начинаю с нескольких калибровочных кривых и фрейма данных необработанных данных:

#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)

(что все равно не работаетиз-за моей неспособности понять «если-еще», но я думаю, что смогу решить это самостоятельно)

Есть ли более векторизованный способ сделать это?

Ответы [ 2 ]

3 голосов
/ 02 ноября 2011

Один из способов, который просто бросается в глаза, - это создание коэффициента data.frame, содержащего несколько полей, что-то вроде [cpd, intercept, coef]

Затем вы можете «присоединить» ваши коэффициенты data.frame к вашему начальному data.frame, используя merge(), тогда у вас будут свои калибровочные коэффициенты в том же фрейме данных.

Вот простой пример использования ваших данных:

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 голос
/ 03 ноября 2011

Кроме того, вы можете создать объект 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(), так что вам не нужно извлекать коэффициенты для "ручного" выполнения прогноза.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...