Advertisement
Guest User

Untitled

a guest
May 1st, 2016
102
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 4.65 KB | None | 0 0
  1. # Author: tim
  2. ###############################################################################
  3. # contains 1) a prospective age calculator
  4. # 2) a quantile age calculator
  5. # 3) a prospective age surface, but with age swapped for e(x). concoluted.
  6.  
  7. library(HMDHFDplus)
  8.  
  9. # define username and password in console
  10. ltf <- readHMDweb("USA","fltper_1x1",username=us,password=pw)
  11.  
  12. # a prospective age calculator, given e(x)
  13. ex2age <- function(ex,Age = (1:length(ex)-1), ex.at = seq(50,5,by=-5)){
  14. # splines make it easier to interpolate to exact values.
  15. out <- splinefun(Age~ex)(ex.at)
  16. names(out) <- ex.at
  17. out
  18. }
  19. # a quantile age calculator, given l(x)
  20. lxquantile2age <- function(lx, Age = (1:length(lx)-1), p = seq(.9,.1,by=-.1), closeout = 2){
  21. # includes closing out the lifetable at open age + 2, whatever. Only OK
  22. # if your lifetable goes to 110+ (could also assume exponential or something)
  23. # same use of spline, but we force monotonic.
  24. out <- splinefun(c(Age,max(Age)+closeout)~c(lx,0),method="monoH.FC")(p)
  25. names(out) <- p
  26. out
  27. }
  28.  
  29. Age <- 0:110
  30. yr1 <- 1950 ; yr2 <- 2010
  31.  
  32. # a look at selected period prospective ages
  33. ex1 <- ltf$ex[ltf$Year == yr1]
  34. ex2 <- ltf$ex[ltf$Year == yr2]
  35.  
  36. prosp <- cbind(ex = seq(50,5,by=-5),
  37. age1 = round(ex2age(ex1),1),
  38. age2 = round(ex2age(ex2),1))
  39. head(prosp)
  40. # ex age1 age2
  41. #50 50 24.1 32.3
  42. #45 45 29.4 37.5
  43. #40 40 34.8 42.8
  44. #35 35 40.3 48.2
  45. #30 30 45.9 53.8
  46. #25 25 51.9 59.6
  47. # or a look at period quantile ages
  48. lx1 <- ltf$lx[ltf$Year == yr1] / 1e5
  49. lx2 <- ltf$lx[ltf$Year == yr2] / 1e5
  50.  
  51. quant <- cbind(prob = seq(.9,.1,by=-.1),
  52. age1 = round(lxquantile2age(lx1),1),
  53. age2 = round(lxquantile2age(lx2),1))
  54. head(quant)
  55. # prob age1 age2
  56. #0.9 0.9 48.1 62.5
  57. #0.8 0.8 60.8 72.1
  58. #0.7 0.7 67.5 77.6
  59. #0.6 0.6 72.2 81.6
  60. #0.5 0.5 75.8 84.7
  61. #0.4 0.4 79.0 87.5
  62.  
  63. # you didn't think I'd not try to make a surface out
  64. # of this stuff, did you?
  65. # [period assumption sinner here]
  66. library(reshape2)
  67. # an age-period matrix of e(x)
  68. EX <- acast(ltf,Age~Year,value.var = "ex")
  69. # a big matrix of prospective ages, sort of:
  70. # we're using thresholds rather than comparing
  71. # with a standard, but in the end such comparisons
  72. # will be possible.
  73. Sand <- apply(EX,2,ex2age,ex.at=5:50)
  74. # define a color ramp, because colors
  75. colRamp <- colorRampPalette(RColorBrewer::brewer.pal(9,"Blues"),space="Lab")
  76.  
  77. # a custom cohort line function,
  78. # not necessarily robust or user-friendly.
  79. # made for the sake of this single plot...
  80. LexLines <- function(EX,N=5,...){
  81. Sand <- apply(EX,2,ex2age,ex.at=5:50)
  82. # make it hmmm.
  83. ages <- as.integer(rownames(EX))
  84. aN <- ages[ages %% N == 0]
  85. aN <- aN[aN < max(Sand)]
  86. aN <- aN[aN > min(Sand)]
  87. years <- as.integer(colnames(EX))
  88. yN <- years[years %% N == 0]
  89.  
  90. EXN <- EX[as.character(aN),as.character(yN)]
  91. for (m in 1:(nrow(EXN)-1)){
  92. for (n in 1:(ncol(EXN)-1)){
  93. segments(yN[n],EXN[m,n],yN[n+1],EXN[m+1,n+1], xpd=FALSE, ...)
  94. }
  95. }
  96. # left side:
  97. offl <- min(yN) - min(years)
  98. if (offl > 0){
  99. EXleft <- EX[as.character(aN+offl),1]
  100. for (m in 1:(nrow(EXN)-1)){
  101. segments(min(years),EXleft[m],yN[1],EXN[m+1,1], xpd=FALSE, ...)
  102. }
  103. }
  104. # right side
  105. offr <- max(years) - max(yN)
  106. if(offr > 0){
  107. EXright <- EX[as.character(aN-offl),ncol(EX)]
  108. for (m in 1:(nrow(EXN)-1)){
  109. segments(max(yN),EXN[m,ncol(EXN)], max(years), EXright[m+1], xpd=FALSE, ...)
  110. }
  111. }
  112. cohL <- min(yN) - aN
  113.  
  114. for (i in 1:(length(cohL)-1)){
  115. rise <- EXN[i+1,1] - EXN[i,1]
  116. run <- N
  117. slope <- rise / run
  118. angle <- atan(slope) * 180 / pi
  119. text(min(yN), EXN[i,1]+1, cohL[i], col = "yellow", cex = .8, srt = angle)
  120. }
  121.  
  122. cohR <- max(yN) - aN
  123.  
  124. for (i in 1:(length(cohR)-1)){
  125. rise <- EXN[i+1,ncol(EXN)] - EXN[i,ncol(EXN)]
  126. run <- N
  127. slope <- rise / run
  128. angle <- atan(slope) * 180 / pi
  129. text(max(yN), EXN[i,ncol(EXN)]+1, cohR[i], col = "yellow", cex = .8, srt = angle)
  130. }
  131.  
  132. }
  133.  
  134. # the complicated plot, will describe in blog.
  135. filled.contour(as.integer(colnames(Sand)),as.integer(rownames(Sand)),t(Sand),
  136. asp=1,color=colRamp, xlab = "Year",
  137. ylab = "e(x)",key.title = title("Age"),
  138. # but quick tip: since filled.contour() spits back a device with crazy coords,
  139. # if you want to plot more in the figure, you need to do it by passing arguments
  140. # to plot.axes (non-intuitively). It's just like panel.first = list(bla bla)
  141. plot.axes = { LexLines(EX,N=5,col="#FFFF0080");
  142. contour(as.integer(colnames(Sand)),as.integer(rownames(Sand)),t(Sand),
  143. drawlabels = TRUE, axes = FALSE,
  144. frame.plot = FALSE, add = TRUE,
  145. labcex = 1);
  146. axis(1); axis(2);
  147. # grids are helpful in this case to match prospective ages...
  148. abline(h=seq(5,50,by=5),col="#FFFFFF30");
  149. abline(v=seq(1935,2015,by=5),col="#FFFFFF30")})
  150.  
  151. # one could do this for quantiles as well, maybe some other time.
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement