Solved – How to get confidence intervals for Patient-Years

biostatisticsconfidence intervalmedicinep-value

In medicine patient-years is a popular concept. Example: $100$ patients are followed for $2$ years. In this case, there are $200$ patient-years in total.
If there were $8$ myocardial infarctions in the group, the rate would be $8$ MIs per $200$ patient years or $8/200*100= 4$ MIs per $100$ patient-years or $8/200*1000= 40$ per $1,000$ patient years, and so on (see here).

See here for an example where confidence intervals are reported for patient years:

For MGUS patients we estimated a mortality rate of 52 [95% CI 48-56] per 1000 patient-years, whereas for MGRS patients the rate was 29 [14-58] per 1000 patient-years.

How can I get CI for patient-years like this?

EDIT

Thanks to @EdM for the great answer. There are two problems:

  1. I get other results. The link in the answer suggests to use the Poisson distribution with poisson.test. Doing so for the results above gives me for example:

poisson.test(52, conf.level = 0.95)$conf.int

38.84 to 68.19. But in the source above it is 52 [95% CI 48-56]

  1. The results differ depending on what time frame the rate refers to. For example, if we choose mortality rate per 10,000 patient years instead the CI's change. For mortality rate per 1,000 patient years the CI's overlap (52[38.84-68.19] and 29[19.42-41.65]). For the morality rate per 10,000 patient years the CI's don't overlap (520[476.26-566.68] and 290[257.58-325.37]).

Best Answer

They indeed used Poisson distribution ("We calculated crude incidence rates as the number of events divided by the total number of person-years at risk following MGUS diagnosis, and 95% confidence intervals (CIs) were based on a Poisson distribution").

We can infer the likely follow-up times: round( sapply( 1:20, function( x ) poisson.test( 52*x, T = x )$conf.int ), 0 ) so something between 11,000 and 15,000 seems to work for the MGUS group (where we had a mortality rate of 52 [95% CI 48-56] per 1000 patient-years), and round( sapply( seq( 0.1, 1, 0.1 ), function( x ) poisson.test( round( 29*x ), T = x )$conf.int ), 0 ) suggests around 300 py (where the rate was 29 [14-58] per 1000 patient-years).

This seems extremely unbalanced, but so was the sample: they had 2,891 MGUS and 44 MGRS patients. They write that "Overall follow-up time for the 2935 patients was 11,050 person-years" so everything seems to check.

UPDATE: AAh, this whole calculation was unnecessary: they've given the number of deaths! "Of the 2891 MGUS patients 566 (20%) and of the 44 MGRS patients eight (18%) died during follow-up." So we actually know the follow-up time (up to rounding): $566/52=10.9$ in the MGUS group, $8/29=0.28$ in the MGRS (in 1000 py). poisson.test(566,10.9) and poisson.test(8,0.28) checks basically OK (I mean the CIs match the presented ones, with a little difference in the MGRS group), and $10.9+0.28= 11.18$ also checks out more-or-less with their presented overall follow-up time.

(I don't know what is the reason for the difference in the MGRS group; I checked that no follow-up time for which the rate is rounded to 29 will result in the CI they presented in the paper. Perhaps its just a rounding error on their part; my best idea is to write an email to the corresponding author.)

Related Question