interp: Interpolate between two population age distributions.

View source: R/AGEINT.R

interpR Documentation

Interpolate between two population age distributions.

Description

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.

Usage

interp(
  popmat,
  datesIn,
  datesOut,
  method = c("linear", "exponential", "power"),
  power = 2,
  extrap = FALSE,
  negatives = FALSE,
  ...
)

Arguments

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 "linear", "exponential", or "power". Default "linear".

power

numeric power to interpolate by, if method = "power". Default 2.

extrap

logical. In case datesOut is out of range of datesIn, do extrapolation using slope in extreme pairwise. Default FALSE.

negatives

logical. In case negative output are accepted, set to TRUE. Default FALSE.

...

arguments passed to stats::approx. For example, rule, which controls extrapolation behavior.

Details

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.

Value

numeric matrix (age-period) (or vector if length(datesOut) == 1 of the interpolated data for the requested dates.

Author(s)

Tim Riffe

References

\insertRef

PASDemoTools

Examples

# 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.
## Not run: 
	matplot(seq(0,75,by=5),popmat,type='l',col=1:5)
	text(20,popmat["20",],colnames(popmat),col=1:5)

## End(Not run)
# 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)
interp(popmat, datesIn, datesOut, "exponential", rule = 2)
interp(popmat, datesIn, datesOut, "power", rule = 2)

# ----------------------------------------------------------
# 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"))
 (p_exp <- interp(cbind(popA_earlier,popA_later),c(d1,d2),dout,method = "exponential"))
 (p_pow <- interp(cbind(popA_earlier,popA_later),c(d1,d2),dout,method = "power"))

 
## Not run: 
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"))


## End(Not run)

timriffe/DemoTools documentation built on Jan. 28, 2024, 5:13 a.m.