Calculate "x" when cumulative probability is 50%

Viewed 58

I have the cumulative probability of getting a specific disease at different ages (this is an example from published data). I want to get the age at which the cumulative probability is 50%. How can I get this done in R?

data<-structure(list(Age = structure(1:65, .Label = c("cumF0", "cumF1", 
"cumF2", "cumF3", "cumF4", "cumF5", "cumF6", "cumF7", "cumF8", 
"cumF9", "cumF10", "cumF11", "cumF12", "cumF13", "cumF14", "cumF15", 
"cumF16", "cumF17", "cumF18", "cumF19", "cumF20", "cumF21", "cumF22", 
"cumF23", "cumF24", "cumF25", "cumF26", "cumF27", "cumF28", "cumF29", 
"cumF30", "cumF31", "cumF32", "cumF33", "cumF34", "cumF35", "cumF36", 
"cumF37", "cumF38", "cumF39", "cumF40", "cumF41", "cumF42", "cumF43", 
"cumF44", "cumF45", "cumF46", "cumF47", "cumF48", "cumF49", "cumF50", 
"cumF51", "cumF52", "cumF53", "cumF54", "cumF55", "cumF56", "cumF57", 
"cumF58", "cumF59", "cumF60", "cumF61", "cumF62", "cumF63", "cumF64"
), class = "factor"), NormCumFreq = c(0.0175245968789, 0.0578992981113, 
0.115553204108, 0.173581449516, 0.222035397344, 0.270097945681, 
0.315896329923, 0.354579579166, 0.387149573944, 0.415871590616, 
0.440978280114, 0.461444925286, 0.47917749443, 0.493999004038, 
0.505508619684, 0.51512487903, 0.52411789833, 0.532735008033, 
0.540812972269, 0.548113686003, 0.554798158422, 0.561563099934, 
0.567823106219, 0.573724015785, 0.579703589596, 0.585608672506, 
0.591383628199, 0.597301585054, 0.603266669771, 0.609342088192, 
0.61559812477, 0.622057526279, 0.628818973321, 0.635910562207, 
0.643342620371, 0.650990220485, 0.659028041826, 0.667365640833, 
0.676046511395, 0.684819235513, 0.693721906451, 0.702852737329, 
0.712051335692, 0.721215208117, 0.730622008883, 0.740269523173, 
0.750050662044, 0.760004826004, 0.770091216483, 0.780442405891, 
0.790907696368, 0.8018259855, 0.813018530957, 0.8246166078, 0.836600903053, 
0.848877171158, 0.861608224775, 0.874792841362, 0.888399062405, 
0.902531605004, 0.917202798245, 0.932317029944, 0.948013615225, 
0.96439871036, 0.981432598965), AgeNum = c(0, 1, 2, 3, 4, 5, 
6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 
23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 
39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 
55, 56, 57, 58, 59, 60, 61, 62, 63, 64)), row.names = c(NA, 65L
), class = "data.frame")

enter image description here

Thanks.

2 Answers

Use approx() to linearly interpolate age as a function of the cumulative frequency, then predict the value for cumfreq==0.5.

a50 <- with(data, approx(NormCumFreq,AgeNum, xout=0.5))$y

This is basically equivalent to @neilfws's answer. Linear interpolation should work fine when your values are densely spaced: if you had sparser (x,y) pairs and wanted to use a smooth interpolation function, you could use the combination of interpSpline() and backSpline() from the (built-in) splines package to fit a spline and then invert it.

library(ggplot2); theme_set(theme_bw())
gg0 <- ggplot(data, aes(AgeNum,NormCumFreq)) + geom_step() +
    geom_hline(yintercept=0.5, lty=2) +
    geom_vline(xintercept=a50, lty=2)
print(gg0)

You could try approxfun.

af1 <- approxfun(df1$NormCumFreq, df1$AgeNum)

af1(0.5)
[1] 13.52139

library(ggplot2)
data %>% 
  ggplot(aes(AgeNum, NormCumFreq)) + 
  geom_point() + 
  geom_vline(xintercept = 13.52139) + 
  geom_hline(yintercept = 0.5)

enter image description here

Related