Beer’s Law

Beer’s law for UV-Vis Spectroscopy is: \[\large Abs = \epsilon_\lambda b c \]

where A = absorbance \(\epsilon_\lambda\) = absorption coefficient at a particular wavelength b = pathlength (typically cm) c = concentration (usually in molarity or \(\mu\)grams)

There is a linear relationship between the abosorbance and the concentration, given a fixed pathlength and wavelength. In any experimental situation, the inherent noise in the data will mean that we need to include a constant (I = intercept).

\[\large Abs = \epsilon_\lambda b c + I\] In order to use Beer’s Law to analyze for a particular component in solution (an ~analyte), we construct a calibration curve (in this case, a line!) using experimentally determined data. The object is to determine the absorption coeficcient, \(\epsilon\). We prepare solutions of varying concentrations of the analyte, and measure the absorbance. According to Beer’s Law, a plot of Absorbance versus concentration should result in a straight line with a slope equal to \(\epsilon\).

Lets take an example. The data comes from the widely use Bradford assay for protein1. In the Bradford assay, a dye (Coomassie brilliant blue G-250) changes from red to blue when attched to proteins, and this color absorbtion at 595 nm) is used to measure protein concentration. Here is sample data for a calibration2 for the BSA (Bovine Serum Albumin) standard.

Conc <- c(2.0, 5.0, 10.0, 15.0, 18.0)   # [BSA], in micrograms / ml
Abs <- c(0.115,0.266,0.413,0.701,0.811) # Absorbance

Xdata <- data.frame(Conc,Abs)    #converts x and y data to a data frame
knitr::kable(Xdata[,], col.names = c('Conc(microg/ml)','Abs'), caption = "Bradford assay data")     #  makes a table
Bradford assay data
Conc(microg/ml) Abs
2 0.115
5 0.266
10 0.413
15 0.701
18 0.811

Linear Regression

We use the “lm” command to do linear regression - to find the best fit to the data according to the least squares criterion: the slope (\(\epsilon\)) and intercept are adjusted to minimize the sum of the squares of the deviations of the experimental data from the fitted line .

BL <- lm(Abs ~ Conc)   # linear regression, lm(y(x)~x)
  
summary(BL)            # summarize results of linear regression
## 
## Call:
## lm(formula = Abs ~ Conc)
## 
## Residuals:
##       1       2       3       4       5 
##  0.0018  0.0223 -0.0482  0.0223  0.0018 
## 
## Coefficients:
##             Estimate Std. Error t value Pr(>|t|)    
## (Intercept) 0.026200   0.029054   0.902 0.433649    
## Conc        0.043500   0.002495  17.435 0.000411 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 0.03329 on 3 degrees of freedom
## Multiple R-squared:  0.9902, Adjusted R-squared:  0.987 
## F-statistic:   304 on 1 and 3 DF,  p-value: 0.0004113
coef(BL) 
## (Intercept)        Conc 
##      0.0262      0.0435
plot(Conc, Abs, main = "Beer's Law ", xlab = "", ylab = "Absorbance", xlim = c(0.0,20.0), ylim =  c(0.0, 1.0), sub = "Figure 1. Beer's Law Plot for BSA")

title(xlab="Concentration, ug/ml", line=2, cex.lab=1.0)    

abline(a = 0.0262, b = 0.0435, col = "blue")  # add a line with intercept = 0.262 and slope = 0.0435, taken from regression.

fitted <- coef(BL)

int <- fitted[1]

slope <- fitted[2]

int
## (Intercept) 
##      0.0262
slope
##   Conc 
## 0.0435

From summary(BL) we learn the best fit values for the slope( \(\epsilon\)) and the intercept, the standard deviations of these fitted values, the p values, and the r value - which should be close to 1.

The final step in an analysis is to calculate the concentration of an unknown based on the absorbance measured. Rearranging Beer’s Law, we have, for example, for an absorbance = 0.350

\[\large c = \frac{Abs-I}{\epsilon}\]

val <- (0.350 - int)/slope
val
## (Intercept) 
##    7.443678

The unknown concentration is 7.45 micrgrams/ml.

Residual Plots

In a regression analysis, it can be helpful to plot the residuals (the deviations) of the experimental data from the theoretical best fit line (or curve). The residuals should appear randomly distributed above and below the best fit line.

We can simulate an example, based on the Bradfoed assay. The simulated data exaggerates the magnitude of typical deviations to help visualize.

Scon <- seq(0.5,20,0.5)
length(Scon)
## [1] 40
rnoise <- rnorm(40,0,0.1)
length(rnoise)
## [1] 40
Sabs <- 0.0435 * Scon + 0.026 + rnoise

plot(Scon,Sabs)

SBL <- lm(Sabs ~ Scon)

summary(SBL)
## 
## Call:
## lm(formula = Sabs ~ Scon)
## 
## Residuals:
##      Min       1Q   Median       3Q      Max 
## -0.31328 -0.06232 -0.02171  0.09921  0.34707 
## 
## Coefficients:
##              Estimate Std. Error t value Pr(>|t|)    
## (Intercept) -0.020412   0.042607  -0.479    0.635    
## Scon         0.048289   0.003622  13.332 6.61e-16 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 0.1322 on 38 degrees of freedom
## Multiple R-squared:  0.8239, Adjusted R-squared:  0.8192 
## F-statistic: 177.7 on 1 and 38 DF,  p-value: 6.608e-16
abline(a = 0.052, b = 0.042, col = "blue") 

plot(Scon,residuals(SBL))

abline(a = 0.0, b = 0.0, col = "blue") 

plot(BL$residuals, pch = 16, col = “red”)

Linear Regression Project,

  1. Find real world data that you expect to follow a linear relationship. Data points should be > 10.

  2. Enter the x y data as vector in R. xval <- c(1,3,5)

  3. Use lm command to perform linear regression.

  4. Summarize the results.

  5. Plot the data and the best fit line.

  6. Analysis & Interpretation. p value for intercept and slope.

  7. Make a residual plot. Is it consistent with linear relationship?


  1. Bradford, M.M. (1976), Rapid and sensitive method for the quantitation of microgram quantities of protein utilizing the principle of protein-dye binding, Anal. Biochem., 72 (1–2): 248–254↩︎

  2. Brady and Macnaughtan, Anal Biochem. 2015 Dec 15; 491: 43–51.Evaluation of Colorimetric Assays for Analyzing Reductively Methylated Proteins: Biases and Mechanistic Insights↩︎