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

\begin{equation} \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). \end{equation}

It is a fact that

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

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

\begin{equation} \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) \end{equation}

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)

| cite | improve this answer | |
  • $\begingroup$ 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? $\endgroup$ – patocardo Jul 20 '11 at 13:31
  • $\begingroup$ 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. $\endgroup$ – Macro Jul 20 '11 at 13:56
  • 1
    $\begingroup$ 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). $\endgroup$ – Ludo Jun 11 '12 at 23:12
  • $\begingroup$ @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 :) $\endgroup$ – Macro Jun 11 '12 at 23:15

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.