The interpolation is done by age using a linear, exponential, or power function. This comes from the PAS spreadsheet called AGEINT
. Be aware that this is not cohort-component interpolation.
interp( popmat, datesIn, datesOut, method = c("linear", "exponential", "power"), power = 2, extrap = FALSE, negatives = FALSE, ... )
popmat | numeric. An age-period matrix of data to interpolate over. Age in rows, time in columns. |
---|---|
datesIn | vector of dates. The exact dates in each column. See details for ways to express it. |
datesOut | vector of dates. The desired dates to interpolate to. See details for ways to express it. |
method | string. The method to use for the interpolation, either |
power | numeric power to interpolate by, if |
extrap | logical. In case |
negatives | logical. In case negative output are accepted, set to |
... | arguments passed to |
numeric matrix (age-period) (or vector if length(datesOut) == 1
of the interpolated data for the requested dates.
The age group structure of the output is the same as that of the input. Ideally, datesOut
should be within the range of datesIn
. If not, the left-side and right-side output are held constant outside the range if rule = 2
is passed in, otherwise NA
is returned (see examples). Dates can be given in three ways 1) a Date
class object, 2) an unambiguous character string in the format "YYYY-MM-DD"
, or 3) as a decimal date consisting in the year plus the fraction of the year passed as of the given date.
For methods "exponential"
and "power"
, calculations are carried out using linear interpolation through log(popmat)
, or popmat^(1/power)
respectively, then back-transformed. If the data contain 0s, method = "exponential"
will fail, but "power"
would still generally work.
United States Census Bureau (2017). “Population Analysis System (PAS) Software.” https://www.census.gov/data/software/pas.html, https://www.census.gov/data/software/pas.html.
Tim Riffe
# Example of interpolating over time series of age-structured # data. NOTE: age classes must conform. They don't have to be # uniform, just the same in each year. popmat <- structure(c(2111460L, 1971927L, 1651421L, 1114149L, 921120L, 859806L, 806857L, 847447L, 660666L, 567163L, 493799L, 322936L, 320796L, 163876L, 133531L, 120866L, 2548265L, 2421813L, 2581979L, 2141854L, 1522279L, 1321665L, 1036480L, 1024782L, 935787L, 789521L, 719185L, 481997L, 479943L, 268777L, 202422L, 167962L, 3753848L, 3270658L, 2930638L, 2692898L, 2222672L, 1788443L, 1514610L, 1491751L, 1054937L, 972484L, 796138L, 673137L, 554010L, 352264L, 293308L, 195307L, 3511776L, 3939121L, 4076601L, 3602857L, 2642620L, 2105063L, 1993212L, 1914367L, 1616449L, 1408498L, 994936L, 776537L, 706189L, 507085L, 315767L, 240302L, 3956664L, 3936424L, 3995805L, 4371774L, 4012982L, 3144046L, 2406725L, 2301514L, 2061252L, 1871502L, 1538713L, 1210822L, 896041L, 638954L, 401297L, 375648L), .Dim = c(16L, 5L), .Dimnames = list(c("0", "5", "10", "15", "20", "25", "30", "35", "40", "45", "50", "55", "60", "65", "70", "75"), c("1960", "1976", "1986", "1996", "2006"))) # We have irregularly spaced census inputs. if (FALSE) { matplot(seq(0,75,by=5),popmat,type='l',col=1:5) text(20,popmat["20",],colnames(popmat),col=1:5) } # census dates as decimal: no need for year rounding. # could also specify as "YYYY-MM-DD" # (rounded to 2 digits here- not necessary) datesIn <- c(1960.73, 1976.90, 1986.89, 1996.89, 2006.89) # could ask for single years or anything datesOut <- seq(1960, 2005, by = 5) # NOTE: rule is an argument to approx(), which does the work. # if not passed in, 1960 is returned as NAs (outside the range # of dates given). In this case, rule = 2 assumes constant # equal to nearest neighbor, meaning 1960 data will be returned # as equal to 1960.73 input data. So, function should only be # allowed to extrapolate for short distances. interp(popmat, datesIn, datesOut, "linear", rule = 2)#> 1960 1965 1970 1975 1980 1985 1990 #> 0 2111460 2226806.8 2361873.3 2496939.7 2922369.8 3525764.7 3678563.6 #> 5 1971927 2090728.1 2229839.4 2368950.7 2685218.4 3110065.7 3478550.0 #> 10 1651421 1897152.8 2184894.9 2472637.0 2690171.5 2864675.5 3287032.5 #> 15 1114149 1385534.3 1703315.7 2021097.1 2312848.6 2588646.4 2975895.2 #> 20 921120 1079867.6 1265754.8 1451641.9 1739618.2 2090165.2 2353275.8 #> 25 859806 981768.8 1124582.3 1267395.9 1466511.0 1700133.6 1886911.8 #> 30 806857 867493.4 938496.2 1009498.9 1184848.7 1424153.0 1663455.2 #> 35 847447 894275.7 949110.3 1003944.9 1169687.3 1403405.5 1623184.6 #> 40 660666 733317.0 818388.4 903459.9 972760.5 1032395.1 1229567.2 #> 45 567163 625880.9 694637.3 763393.6 846296.3 937869.4 1108084.4 #> 50 493799 553316.5 623009.2 692701.8 743064.3 781579.3 857964.2 #> 55 322936 364939.1 414123.1 463307.1 541309.7 636975.4 705294.4 #> 60 320796 362821.8 412032.4 461243.0 502926.8 539997.3 601337.7 #> 65 163876 191577.1 224014.1 256451.0 294683.9 336469.2 400413.3 #> 70 133531 151723.0 173025.1 194327.2 230624.9 276113.4 300292.7 #> 75 120866 133302.6 147865.4 162428.1 176447.4 190133.6 209300.4 #> 1995 2000 2005 #> 0 3557527.6 3650136.2 3872580.2 #> 5 3812781.5 3938282.2 3936933.7 #> 10 3860014.0 4051473.4 4011075.4 #> 15 3430874.7 3841990.2 4226448.7 #> 20 2563249.8 3068802.6 3753983.6 #> 25 2045221.8 2428186.7 2947678.2 #> 30 1902756.2 2121814.5 2328571.0 #> 35 1834492.6 2034769.7 2228343.2 #> 40 1510323.2 1754782.7 1977184.2 #> 45 1326091.4 1552492.2 1783994.2 #> 50 957363.2 1164050.6 1435939.1 #> 55 756994.4 911599.6 1128742.1 #> 60 677427.2 765233.0 860159.0 #> 65 477823.8 548096.3 614030.8 #> 70 311522.2 342366.8 385131.8 #> 75 231797.9 282394.6 350067.6interp(popmat, datesIn, datesOut, "exponential", rule = 2)#> 1960 1965 1970 1975 1980 1985 1990 #> 0 2111460 2218948.4 2351788.2 2492580.6 2873748.4 3488582.4 3676827.6 #> 5 1971927 2081895.6 2218483.9 2364033.5 2658486.2 3089918.2 3465395.4 #> 10 1651421 1858284.9 2133680.0 2449888.1 2685484.9 2861244.6 3247429.1 #> 15 1114149 1324031.9 1620570.6 1983524.0 2299556.2 2578747.5 2948076.4 #> 20 921120 1051793.1 1228553.8 1435020.1 1711998.6 2069075.1 2345578.3 #> 25 859806 963180.6 1100131.4 1256554.7 1451716.5 1688979.6 1881441.8 #> 30 806857 862021.1 931428.3 1006423.9 1165954.0 1409723.1 1649637.0 #> 35 847447 891052.4 944972.8 1002156.1 1151415.8 1389460.6 1612080.1 #> 40 660666 724282.4 806602.6 898279.2 971244.4 1031286.5 1204663.8 #> 45 567163 618932.0 685588.4 759423.3 842272.5 934883.1 1091224.7 #> 50 493799 545343.6 612578.8 688103.5 742232.8 780973.1 853287.3 #> 55 322936 358959.5 406281.0 459840.8 534635.4 631916.7 703726.2 #> 60 320796 356804.8 404139.3 457753.3 501800.0 539170.1 597445.2 #> 65 163876 186748.7 217621.0 253596.8 292311.7 334690.2 394523.0 #> 70 133531 149036.6 169496.4 192764.9 227111.0 273433.6 300116.1 #> 75 120866 131838.3 145958.8 161591.8 176010.5 189812.4 208314.8 #> 1995 2000 2005 #> 0 3556299.5 3644494.9 3868463.7 #> 5 3803075.0 3938282.0 3936933.6 #> 10 3830078.7 4051299.9 4010951.7 #> 15 3409983.7 3826258.8 4214826.3 #> 20 2557582.2 3009263.5 3708313.7 #> 25 2041201.1 2384782.1 2914476.7 #> 30 1892407.8 2113566.9 2322482.6 #> 35 1826211.4 2027223.3 2222776.6 #> 40 1491192.1 1743387.8 1968695.4 #> 45 1313261.1 1538665.5 1773622.8 #> 50 953890.8 1139428.0 1416994.3 #> 55 755845.6 891578.7 1113316.8 #> 60 674527.6 760467.2 856611.6 #> 65 473345.9 544881.0 611640.3 #> 70 311394.3 340205.7 383522.8 #> 75 231068.1 276120.6 345231.6interp(popmat, datesIn, datesOut, "power", rule = 2)#> 1960 1965 1970 1975 1980 1985 1990 #> 0 2111460 2222819.3 2356853.9 2494812.1 2897460.8 3507911.3 3677699.3 #> 5 1971927 2086240.2 2224190.1 2366556.1 2671597.3 3100302.9 3471895.4 #> 10 1651421 1877031.0 2159565.8 2461900.3 2687809.4 2862982.5 3266817.3 #> 15 1114149 1353188.2 1662598.7 2003837.7 2306105.9 2583813.6 2961729.8 #> 20 921120 1065271.5 1247381.3 1443853.7 1725476.3 2080029.1 2349385.0 #> 25 859806 972158.3 1112484.7 1262267.9 1458971.7 1694729.9 1884148.7 #> 30 806857 864703.1 934983.8 1008010.1 1175173.7 1417218.4 1656426.2 #> 35 847447 892639.9 947051.2 1003072.0 1160333.6 1396701.3 1617544.8 #> 40 660666 728675.3 812545.5 900983.1 971996.7 1031847.6 1216779.0 #> 45 567163 622315.6 690149.3 761491.2 844257.8 936408.3 1099456.9 #> 50 493799 549211.4 617841.7 690511.4 742645.9 781279.4 855592.8 #> 55 322936 361854.5 410240.3 461661.2 537901.8 634532.7 704503.2 #> 60 320796 359717.4 408124.6 459586.5 502358.3 539589.9 599361.6 #> 65 163876 189068.3 220855.9 255112.3 293477.4 335604.4 397400.3 #> 70 133531 150335.6 171278.6 193586.9 228826.6 274824.4 300204.0 #> 75 120866 132551.4 146919.7 162027.3 176226.9 189975.5 208801.2 #> 1995 2000 2005 #> 0 3556909.3 3647294.3 3870547.3 #> 5 3808021.3 3938282.1 3936933.7 #> 10 3845553.6 4051386.8 4011013.5 #> 15 3420741.8 3834028.4 4220753.4 #> 20 2560466.6 3038245.6 3732125.4 #> 25 2043245.3 2405933.2 2931759.7 #> 30 1897728.2 2117641.6 2325586.0 #> 35 1830458.3 2030952.6 2225612.8 #> 40 1501175.5 1748997.7 1973046.1 #> 45 1319919.9 1545454.6 1778960.1 #> 50 955666.9 1151399.4 1426889.4 #> 55 756428.5 901307.6 1121380.0 #> 60 676013.6 762814.2 858428.8 #> 65 475668.5 546465.2 612864.0 #> 70 311458.8 341269.9 384347.2 #> 75 231440.8 279168.8 347760.1# ---------------------------------------------------------- # standard example data, taken from AGEINT PAS spreadsheet. # YYYY-MM-DD dates as character d1 <- "1980-04-07" d2 <- "1990-10-06" dout <- "1985-07-01" (p_lin <- interp(cbind(popA_earlier,popA_later),c(d1,d2),dout,method = "linear"))#> [1] 151269.21 698637.56 935163.70 838408.52 669361.53 555363.48 452291.31 #> [8] 373698.99 370798.20 334150.36 258103.71 223758.80 190651.53 158396.80 #> [15] 119288.68 80400.82 46479.94 51836.50#> [1] 142611.79 658653.23 881642.53 790424.84 631052.72 523578.99 426405.83 #> [8] 352311.49 349576.73 315026.30 243331.95 210952.67 179740.18 149331.46 #> [15] 112461.57 75799.33 43819.81 48869.80#> [1] 146938.84 678637.75 908392.88 814407.50 650199.80 539465.16 439343.62 #> [8] 363001.15 360183.41 324584.67 250715.00 217353.29 185193.77 153862.40 #> [15] 115873.82 78099.19 45149.37 50352.58#> [1] 1980.26502732240442#> [1] 1990.7616438356165#> [1] 1985.49589041095896# these were set to different dates: recreate above dates... expcheck <- c(142611.789832724, 658653.225145641, 881642.532889494, 790424.835149364, 631052.720366013, 523578.990638372, 426405.833143345, 352311.49478387, 349576.729583329, 315026.304975883, 243331.949093535, 210952.668139616, 179740.182668986, 149331.458251614, 112461.568530899, 75799.3288538202, 43819.8095485345, 48869.8021063505) lincheck <- c(151269.209810283, 698637.560216026, 935163.70169507, 838408.524061807, 669361.533645738, 555363.482079782, 452291.311354737, 373698.987198367, 370798.204791894, 334150.355163834, 258103.707303228, 223758.803211712, 190651.52632461, 158396.803770816, 119288.683114125, 80400.8181463556, 46479.9437144632, 51836.5021355072) stopifnot(all(abs(expcheck - p_exp)<1e-6)) stopifnot(all(abs(lincheck - p_lin)<1e-6)) # do controlled spreadsheet test, passing in decimal dates, etc # } if (FALSE) { age <- c(0,1,seq(5,80,by=5)) plot(age, popA_later, type = 'l', lwd = 2, main = "Interpolation options") lines(age, popA_earlier, lwd = 2, lty = "8282") lines(age, p_lin,col = "blue") lines(age, p_pow,col = gray(.4)) lines(age, p_exp,col = "red") text(30, popA_earlier[8], d1, pos = 1, cex = 1) text(20, popA_later[6], d2, pos = 4, cex = 1) legend("topright", lty = 1, col = c("blue", gray(.4), "red"), legend = c("linear", "power 2", "exponential"), title = paste0("Interpolated 1985-07-01")) }