ELISA analysis in R

OK, here’s a little taste of what I usually do, rather than some random ramblings… I have a PhD student who is running enzyme-linked immunosorbent assays, or “ELISAs” to the initiated. This is a standard technique for measuring (in a semi-quantitative way) the amount of a given substance in a sample. Basically (and this is a pretty basic description), you stick an antigen to a surface (like the bottom of a plastic tray) and then add an antibody that sticks to the antigen. The antibody has an enzyme stuck to it and when you add the substance of interest the enzyme catalyses a reaction that causes a change in the intensity of a colour. You can shine a light through the sample to see how much the colour has changed and that gives you an idea about the concentration of your sample.

Usually what you would do is use known concentrations of a substance to see what those concentrations look like, and then you can read off that “standard curve” to infer the concentrations in other samples based on their colour. However, the maths behind the curve fitting is a little bit challenging. The result is that there are a lot of computer packages that do it for you and charge you for the privilege. However, if you are feeling fancy you can (as with many other things) just do it in R. You can do this longhand by fitting the non-linear regression (which isn’t that much more work), but the “drc” package (2015 paper available here) has all the tools you need to (i) create your standard curve, and (ii) read off your estimated values. Here is a worked example (and check out the fancy R syntactical highlighting in WordPress!):

#Install the package and load it into the workspace

install.packages("drc")
library(drc)

# For the sake of this example, here is some data from my lab:

dat<-data.frame(Conc=rep(c(0.0001,0.15,0.4,1,2,5),each=3),
                  OD=c(2.45,2.51,2.52,2.07,2.15,2,1.59,1.44,1.53,
1.05,1.1,1.04,0.661,0.769,0.822,0.56,0.547,0.567))

model1<-drm(OD~Conc,
             fct=LL.4(names=c("Slope", "Lower", "Upper", "ED50")),
data=dat)
plot(model1)

Rplot02

So that’s the standard curve sorted. Now the next step is to take some unknown samples and calculate their colour (“optical density”) using the ELISA, and then read that OD value from the plot:


# Here are some observed values from new samples
response<-c(2.45,1.67,1.42)
# Estimate the concentration
DOSEx<-ED(model1,response,type="absolute",display=F)
# And here are the estimates including standard errors
DOSEx

#            Estimate  Std. Error
# e:1:2.45 0.01805795 0.003982093
# e:1:1.67 0.32610628 0.023066872
# e:1:1.42 0.49918728 0.041480395
# We can add those to our plot
points(y=response,x=DOSEx[,1],col="blue",pch=19,cex=2)
# With error bars
arrows(DOSEx[,1],response,DOSEx[,1]+DOSEx[,2]*1.96,response,length=0.1,angle=90,lwd=3,col="blue")
arrows(DOSEx[,1],response,DOSEx[,1]-DOSEx[,2]*1.96,response,length=0.1,angle=90,lwd=3,col="blue")

 

Rplot01
And there you have it: ELISA standard curve plotting and estimated doses with standard errors from R in a few lines of code (rather than a few hundred dollars’ worth of software!).

Leave a comment