# Generating data with a pre-specified odds ratio

I have to simulate (in javascript) the likelihood that members of a certain population would have a disease, given a contextual value. All information I have comes from papers that show odds ratios with $95\%$ confidence interval.

I found Box-Muller method and other approaches to normal distribution, but I cannot realize the way to generate random numbers with OR, CI percentage and the interval.

It appears you're asking how to generate bivariate binary data with a pre-specified odds ratio. Here I will describe how you can do this, as long as you can generate a discrete random variables (as described here), for example.

If you want to generate data with a particular odds ratio, you're talking about binary that comes from a $2 \times 2$ table, so the normal distribution is not relevant. Let $X,Y$ be the two binary outcomes; the $2 \times 2$ table can be parameterized in terms of the cell probabilities $p_{ij} = P(Y = i, X = j)$. The parameters $p_{11}, p_{01}, p_{10}$ will suffice, since $p_{00} = 1 - p_{11} - p_{01} - p_{10}$.

It can be shown that there is a 1-to-1 invertible mapping $\{ p_{11}, p_{01}, p_{10} \} \longrightarrow \{ M_{X}, M_{Y}, OR \}$ where $M_{X} = p_{11} + p_{01}, M_{Y} = p_{11} + p_{10}$ are the marginal probabilities and $OR$ is the odds ratio.

That is, we can map back and forth at will between the $\{$cell probabilities $\}$ and $\{$ the marginal probabilities & Odds ratio$\}$. Using this fact, you can generate bivariate binary data with a pre-specified odds ratio. This rest of this answer will walk one through that process and supply some crude R code to carry it out

The '$\longrightarrow$' is simple enough; to generate data with a particular odds ratio you have to invert this mapping. For a fixed value of $M_{X}, M_{Y}$, we have

$$\log( OR ) = \log(p_{11}) + \log \left(1 - M_{Y} - M_{X} + p_{11}\right) - \log \left(M_{Y}-p_{11}\right) - \log \left(M_{X}-p_{11}\right).$$

It is a fact that

$${\rm max}\Big(0, M_X + M_Y-1\Big) \le p_{11}\le {\rm min}\Big(M_X, M_Y\Big).$$

As $p_{11}$ moves through this range, $OR$ increases monotonically from 0 to $\infty$, thus there is a unique root of

$$\log(p_{11}) + \log \left(1 - M_{Y} - M_{X} + p_{11}\right) - \log \left(M_{Y}-p_{11}\right) - \log \left(M_{X}-p_{11}\right) - \log(OR)$$

as a function of $p_{11}$. After solving for this root, $p_{10} = M_{Y} - p_{11}$ and $p_{01} = M_{X} - p_{11}$ and $p_{00} = 1 - p_{11} - p_{01} - p_{10}$, at which point we have the cell probabilities and the problem reduces to simply generating discrete random variables.

The width of the confidence interval will be a function of the cell counts so more information is needed to precisely reproduce the results.

Here is some crude R code to generate data as specified above.

 # return a 2x2 table of n outcomes with row marginal prob M1, column marginal prob
# M2, and odds ratio OR
f = function(n, M1, M2, OR)
{
# find p11
g = function(p) log(p) + log(1-M1-M2+p) - log(M1-p) - log(M2-p) - log(OR)
br = c( max(0,M1+M2-1), min(M1,M2) )
p11 = uniroot(g, br)$root # fill in other cell probabilities p10 = M1 - p11 p01 = M2 - p11 p00 = 1-p11-p10-p01 # generate random numbers with those cell probabilities x = runif(n) n11 = sum(x < p11) n10 = sum(x < (p11+p10)) - n11 n01 = sum(x < (p11+p10+p01)) - n11 - n10 n00 = n - (n11+n10+n01) z = matrix(0,2,2) z[1,] = c(n11,n10) z[2,] = c(n01,n00) return(z) }  • The answer is very proof. Furthermore and continuing the question (remember I am not a statistician), as I understand, two flat random numbers (lower limit < p1 < OR, and OR< p2 < upper limit) will be necessary to obtain the result number I need (Am I correct?). But how do I input the % of confidence interval? – patocardo Jul 20 '11 at 13:31 • This ins't a proof, this is just walking you through the steps of generating data with a specific odds ratio. The confidence interval for an odds ratio is obtained by getting a confidence interval for the log odds ratio, which has standard error$\sqrt{ 1/n_{11} + 1/n_{10} + 1/n_{01} + 1/n_{00} }$, and then you exponentiate. So, different cell counts could give the exact same confidence interval width, so you actually need more information to generate data that will produce the same confidence interval. – Macro Jul 20 '11 at 13:56 • Instead of a numerical solution (uniroot), I once came across an analytical solution to calculate p11 given (M1,M2,OR), e.g. S<-sqrt((1+(M1+M2)*(OR-1))^2+4*OR*(1-OR)*M1*M2);p11=(1+(M1+M2)*(OR-1)-S)/2/(OR-1). I vaguely recall I encountered it somewhere on wikipedia (but can't find it back anymore). – Ludo Jun 11 '12 at 23:12 • @Ludo - Yes, you can show$p_{11}\$ is the solution to a quadratic equation. If there appeared to be some interest, I'd take the time to write that solution here. But there isn't and the answer is already quite long as it is :) – Macro Jun 11 '12 at 23:15