Modelling asymmetry in concentration-effect relationships

Introduction

Why do we assume symmetry in our concentration-effect relationship?

I recently came across an article published by Piet Hein van der Graaf and Rik Schoemaker from 1999 on the use of asymmetry in concentration-effect curves.

“Analysis of asymmetry of agonist concentration–effect curves”: https://www.sciencedirect.com/science/article/pii/S105687199900026X

They make a valid point on an assumption we commonly do not investigate: a logistic or a Hill model assumes a symmetric relationship. However, is it really?

They analysed different concentration-effect curves with a1-adrenoceptor agonists in rat aorta and showed that a asymmetrical curve was able to better fit the data than the ‘standard’ symmetrical hill equation. So what does it mean to include asymmetry in a relationship?

Terminology

To understand asymmetry, it is important to know the following terminology:

Mid-point: also called the EC50, in which half of the effect is reached.

Inflection point: as wikipedia puts it, “a point on a continuous plane curve at which the curve changes from being concave (concave downward) to convex(concave upward), or vice versa”

Equations

I found out that one complicating factor in exploring and understanding asymmetry equations is that there are different parameterizations of the formula’s available. In this post I will use the parameterization as presented in:
Assessing the (a)symmetry of concentration-effect curves:empirical versus mechanistic models

Let’s start with a standard Hill equation, which we can rewrite as:

a = Maximal effect
m= hill coefficient
xb (log10 [A]) = not named (EC50 in hill equation)
x = log10 [A]

Since this curve is symmetrical, the mid-point ánd the inflection point are equal.

We can use the Richards function (Richards, F. J. (1959). “A Flexible Growth Function for Empirical Use”. Journal of Experimental Botany. 10 (2): 290–300. doi:10.1093/jxb/10.2.290) to introduce asymmetry in our relationship with the parameter s.

s = asymmetry factor

In this equation, when s == 1, we return to the previous (symmetrical) Hill equation. In all other scenario’s, the concentration-effect relationship is asymmetrical.

We can calculate the mid-point (x50) and the inflection point (xi) using the following equations:

Application

Let’s use R to simulate some scenario’s with this Richards function! First define the previously described equations in R

# Richards equation
E = a/((1+10^(m*(xb-x)))^s)

# mid-point
x50 = xb - (1/m)*log10(2^(1/s)-1)

# Inflection point
xi = xb + (1/m) * log10(s)

This will give us the effect (E) at different values for x, the mid-point (x50) and the inflection point (xi).

If we simulate a range of concentrations over multiple orders of magnitude (e.g. from 10-10 to 1010) and define our parameter objects, we can simulate the effect at these concentrations:

x<-seq(-10,10,length.out = 100)

a  <- 1
m  <- 1
xb <- 0
s  <- 0.5


# Richards equation
E = a/((1+10^(m*(xb-x)))^s)

# Mid-point
x50 = xb - (1/m)*log10(2^(1/s)-1)
# Effect at mid-point
E50 = a/2

# Inflection point
xi = xb + (1/m) * log10(s)
# Effect at inflection point
Ei =  a/((1+10^(m*(xb-xi)))^s)

# Data frame with C-E
df<-data.frame(logC=x,E=E)

# Data frame with mid-point and inflection point
points <-data.frame(Point='Mid-point',x=10^x50,E=E50)
row <-data.frame(Point='Inflection point',x= 10^xi,E=Ei)
points <- rbind(points,row)
 

Remember that x equals the log10 of [A], which we can backtransform to [A].

We can now use ggplot2 to plot these results:

library(ggplot2)
ggplot(df,aes(x=10^logC,y=E))+
  geom_line() +
  theme_bw()+
  xlab("Log10 [Concentration]")+
  ylab('Effect')+
  geom_point(data=points,aes(x=x,y=E,shape=Point),size=3)+
  scale_shape_manual(values=c(1,3))+
scale_x_log10()
 
a=1, m= 1, xb=0, s=0.5

or in a case where s = 0.1


a=1, m= 1, xb=0, s=0.1

Asymmetry in PMX models

Due to the existence of asymmetrical curves in biology, it would be interesting to investigate asymmetrical concentration-effect relationships in population PK/PD models. The difference between the mid-point and the inflection point can give an indication on the severity of this asymmetry in the curve and whether, if at all, there is a significant difference with a parsimonious symmetrical relationship (EMAX/Hill).

Shiny simulations

We can create a very simple Shiny application to have an interactive interface to explore different parameter values:

ui.R
library(shiny)

# Define UI for application that draws a histogram
shinyUI(fluidPage(
  
  # Application title
  titlePanel("Asymmetry function simulation"),
  
  # Sidebar with a slider input for number of bins 
  sidebarLayout(
    sidebarPanel(
      numericInput("a","Emax",min = 0,value = 1),
      numericInput("m","Hill coefficient",min = 0.1,value = 1),
      numericInput("xb","Log10 Xb",value = 0),
      numericInput("s","Asymmetry factor",min = 0.1,value = 1,step = 0.1),
      numericInput("min_C","Log10 minimal concentration",value = -10),
      numericInput("max_C","Log10 maximal concentration",min = 0,value = 10)
    ),
    
    # Show a plot of the generated distribution
    mainPanel(
       plotOutput("distPlot")
    )
  )
))
 

server.R

library(shiny)

shinyServer(function(input, output) {
   
  
  c_range <- reactive({
    x<-seq(input$min_C,input$max_C,length.out = 100)
    return(x)
  })
  
  
  
  df <- reactive({
    # Richards equation
    E = input$a/((1+10^(input$m*(input$xb-c_range())))^input$s)
    
    df<-data.frame(logC=c_range(),E=E) 
    return(df)
  }) 
  
  
  points <- reactive({
    # Mid-point
    x50 = input$xb - (1/input$m)*log10(2^(1/input$s)-1)
    # Effect at mid-point
    E50 = input$a/2
    
    # Inflection point
    xi = input$xb + (1/input$m) * log10(input$s)
    # Effect at inflection point
    Ei =  input$a/((1+10^(input$m*(input$xb-xi)))^input$s)
    
    points <-data.frame(Point='Mid-point',x=10^x50,E=E50)
    row <-data.frame(Point='Inflection point',x= 10^xi,E=Ei)
    points <- rbind(points,row)
    return(points)
  })
  
  output$distPlot <- renderPlot({

    
     ggplot(df(),aes(x=10^logC,y=E))+
       geom_line() +
       theme_bw()+
       xlab("Concentration")+
       ylab('Effect')+
       geom_point(data=points(),aes(x=x,y=E,shape=Point),size=3)+
       scale_shape_manual(values=c(1,3))+
       scale_x_log10()
    
    
  })
  
})
 

Acknowledgments

I would like to thank Hadi Taghvafardfor his input on asymmetrical equations.

COMMENT

Any suggestions or typo’s? Leave a comment or contact me at info@pmxsolutions.com!

Leave a Reply

Your email address will not be published. Required fields are marked *