I am trying to calculate confidence intervals for transition probabilities between a set of discrete states over time (involving multiple time steps).

Here is a toy example to get the transition probabilities:

# create a toy dataset
states<- c("A","B","C")
t1 <- sample(states,30,c(2/3,1/6,1/6),replace=T)
t2 <- sample(states,30,c(2/3,1/6,1/6),replace=T)
t3 <- sample(states,30,c(2/3,1/6,1/6),replace=T)
df.t <- data.frame(t1=t1,t2=t2,t3=t3)    

transition.matrix.t1 <- table(t1,t2)
transition.matrix.t2 <- table(t2,t3)    

prob.trans.t1 <- t(apply(transition.matrix.t1,1,function(x) x/sum(x)))
prob.trans.t2 <- t(apply(transition.matrix.t2,1,function(x) x/sum(x)))

Each row of df.t is a sample observation over 3 time periods. prob.trans.t1 contains the transition probabilities for the time step t1->t2.

In reality, I don't have any previous knowledge about the underlying probabilities and I only have a randomly picked sample. I would like to calculate a 95% confidence interval for the above transition probabilities transition.matrix.t1, transition.matrix.t2.

  • $\begingroup$ prob.trans.t1 is a stochastic matrix, so I believe your question is how do I calculate confidence intervals for x/sum(x)? We can treat these as multinomial proprtions. This may help. $\endgroup$
    – Zhubarb
    Nov 26, 2013 at 17:02

1 Answer 1


prob.trans.t1 is a stochastic matrix, so I assume your question is "how do I calculate confidence intervals for x/sum(x)?". These can be treated as multinomial proportions. A discussion is provided in this link.

Also, here is an R package that implements a method for building simultaneous confidence intervals for the probabilities of a multinomial distribution given a set of observations, proposed by Sison and Glaz in their paper.

And finally, below is how it can be applied in your toy example:

for (r in 1:nrow(transition.matrix.t1)){
  m <- multinomialCI(transition.matrix.t1[r,], 0.05);
  print(paste(colnames(transition.matrix.t1)[r], " to A: [", m[1,1], m[1,2], "]"));
  print(paste(colnames(transition.matrix.t1)[r], " to B: [", m[2,1], m[2,2], "]"));
  print(paste(colnames(transition.matrix.t1)[r], " to C: [", m[3,1], m[3,2], "]"));

[1] "A  to A: [ 0.5 0.90486071657815 ]"
[1] "A  to B: [ 0 0.27986071657815 ]"
[1] "A  to C: [ 0.0625 0.46736071657815 ]"
[1] "B  to A: [ 0.5 0.997113668612868 ]"
[1] "B  to B: [ 0 0.297113668612868 ]"
[1] "B  to C: [ 0.1 0.597113668612868 ]"
[1] "C  to A: [ 0.5 1 ]"
[1] "C  to B: [ 0 0.351000820903667 ]"
[1] "C  to C: [ 0 0.601000820903667 ]"
  • $\begingroup$ Thanks for your answer. Using a multinomial distribution to calculate the CIs does make a lot of sense. I was pondering to sample multiple datasets using the initial distribution and the transition probabilities to obtain a bootstrapped CI. I will try it and compare both. $\endgroup$ Nov 26, 2013 at 20:04
  • $\begingroup$ @means-to-meaning, yes it would be interesting to compare, pls do share if you have some benchmark results. $\endgroup$
    – Zhubarb
    Nov 27, 2013 at 9:57
  • $\begingroup$ great answer! @ zhubarb $\endgroup$
    – stats_noob
    Dec 14, 2022 at 1:22

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.