set.seed(123) # para generar siempre los mismos números aleatorios
<- 3 # intercepto
a <- 10 # pendiente
b <- 0.3 # error aleatorio
s <- rnorm(7, 0, s) # errores aleatorios normales con media = 0 y s = 0.3
e
<- c(0, 5, 10, 15, 20, 25, 30) # concentraciones de calibrantes
x <- a + b*x + e y
¿Cómo simular una curva de calibración con una pendiente específica?
Hace un tiempo publiqué un post en LinkedIn con una pregunta capciosa sobre cuál de dos curvas de calibración era “más lineal”.
Era capciosa porque, como puede leer en el post, no existe tal cosa de que una curva de calibración sea “más lineal” que otra.
De hecho, ambas curvas fueron creadas en forma artificial a través de una simulación. Sin embargo, ya que es una curva de calibración simulada con la ayuda de un generador de números aleatorios (el cual simula la aleatoriedad del instrumento), aunque especifiquemos una pendiente e intercepto, debido a la aleatoriedad de la simulación, obtendremos valores “similares” pero no iguales a los que especificamos. Lógico, es aleatorio.
Por ejemplo: supongamos que queremos simular una curva de calibración de Cu por AAS entre 0 y 30 ppm, equiespaciada de 5 en 5 ppm (n = 7 puntos). Asumamos que los errores aleatorios son normales con media 0 y desviación estándar \(\sigma = 0.3\) UA. Especifiquemos que nuestra curva tenga pendiente 10 e intercepto = 3. Es decir, nuestro modelo “teórico” de calibración sería:
\[y = a + bx + e\] Donde \(a = 3\), \(b = 10\) y \(e \sim N(0, 0.9)\)
En R
lo simularíamos con el siguiente código:
Listo. Ahora ajustaremos un modelo lineal y veremos que tan “buena” fue la simulación.
<- lm(y ~ x)
fit summary(fit)
Call:
lm(formula = y ~ x)
Residuals:
1 2 3 4 5 6 7
-0.12528 -0.08539 0.39208 -0.11358 -0.15515 0.26139 -0.17406
Coefficients:
Estimate Std. Error t value Pr(>|t|)
(Intercept) 2.957139 0.170292 17.36 1.16e-05 ***
x 10.011840 0.009446 1059.89 1.42e-14 ***
---
Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
Residual standard error: 0.2499 on 5 degrees of freedom
Multiple R-squared: 1, Adjusted R-squared: 1
F-statistic: 1.123e+06 on 1 and 5 DF, p-value: 1.419e-14
Excelente, obtuvimos un intercepto \(a = 2.96\) y una pendiente de \(b = 10.01\), muy cercanos a los valores teóricos de la simulación \(a = 3\) y \(b = 10\).
Sin embargo, quizás Ud. necesita que la simulación genere una pendiente bien específica, por la razones que sean. Por ejemplo, Ud. quiere que la pendiente sea exactamente igual a 1 o a 59,16 mV. En el post de LinkedIn simulé ambas curvas con la misma pendiente.
¿Cómo simular una curva de calibración con una pendiente conocida?
Todo es exactamente igual que la simulación anterior, sólo que agregaremos un paso adicional
set.seed(123) # para generar siempre los mismos números aleatorios
<- 3 # intercepto
a <- 10 # pendiente
b <- 0.3 # error aleatorio
s <- rnorm(7, 0, s) # errores aleatorios normales con media = 0 y s = 0.3
e
<- c(0, 5, 10, 15, 20, 25, 30) # concentraciones de calibrantes
x <- resid(lm(e ~ x)) # errores modificados
e <- a + b*x + e
y
<- lm(y ~ x)
fit2 summary(fit2)
Call:
lm(formula = y ~ x)
Residuals:
1 2 3 4 5 6 7
-0.12528 -0.08539 0.39208 -0.11358 -0.15515 0.26139 -0.17406
Coefficients:
Estimate Std. Error t value Pr(>|t|)
(Intercept) 3.000000 0.170292 17.62 1.08e-05 ***
x 10.000000 0.009446 1058.64 1.43e-14 ***
---
Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
Residual standard error: 0.2499 on 5 degrees of freedom
Multiple R-squared: 1, Adjusted R-squared: 1
F-statistic: 1.121e+06 on 1 and 5 DF, p-value: 1.427e-14
Perfecto, hemos obtenido exactamente un intercepto 3 y una pendiente 10.
Si desea profundizar sus conocimientos de Estadística aplicada en Química pinche la campana de mi perfil de LinkedIn y no se pierda las actualizaciones de los cursos que dictaré durante este año.