This method uses Grabill's redistribution of middle ages and blends into Sprague estimated single-age population counts for the first and final ten ages. Open age groups are preserved, as are annual totals.

graduate_grabill(Value, Age, AgeInt, OAG = TRUE)



numeric vector, presumably counts in grouped ages


integer vector, lower bounds of age groups


integer vector, age interval widths


logical, default = TRUE is the final age group open?


numeric vector in single ages.


Dimension labeling is necessary. There must be at least six age groups (including the open group). One year of data will work as well, as long as it's given as a single-column matrix. Data may be given in either single or grouped ages. If the highest age does not end in a 0 or 5, and OAG == TRUE, then the open age will be grouped down to the next highest age ending in 0 or 5. If the highest age does not end in a 0 or 5, and OAG == FALSE, then results extend to single ages covering the entire 5-year age group.


Shryock HS, Siegel JS, Larmon EA (1973). The methods and materials of demography. US Bureau of the Census.


a5 <- as.integer(rownames(pop5_mat)) p5 <- pop5_mat[,1] p1g <- graduate_grabill(Value = p5, Age = a5, OAG = TRUE) sum(p1g) - sum(p5)
#> [1] 0
p1s <- graduate_sprague(p5, Age = a5, OAG = TRUE) if (FALSE) { plot(seq(0,100,by=5),p5[,1]/5,type = "s", col = "gray", xlab = "Age", ylab = "Count") lines(0:100, p1g, col = "red", lwd = 2) lines(0:100, p1s, col = "blue", lty = 2, lwd =2) legend("topright", lty = c(1,1,2), col = c("gray","red","blue"), lwd = c(1,2,1), legend = c("grouped","Grabill", "Sprague")) } # also works for single ages: grab1 <- graduate_grabill(Value = pop1m_ind, Age = 0:100) if (FALSE) { plot(0:100, pop1m_ind) lines(0:100, grab1) }