Seeking Help with Lee-Carter Model in R

Hey everyone,

I'm new to R and in a bit of a jam while working on a project in R, specifically trying to fit a Lee-Carter model using the StMoMo package.

I'm attempting to create a StMoMoData object using two datasets: one for mortality (males.txt) and another for population data (malespop.txt). Despite having matching years in both datasets, I'm encountering a perplexing error when trying to create a demogdata object : "Number of years doesn't match data."

I'm seeking some guidance on how to tackle this "Number of years" error within the context of fitting a Lee-Carter model.

Here's a snippet of the code I'm working with:

library(StMoMo)
library(demography)

# Read in mortality data
men <- read.table("males.txt", header = TRUE, na.strings = ",")

# Read in population data
pop <- read.table("malespop.txt", header = TRUE, na.strings = ",")

# Create a demogdata object
men_demogdata <- demogdata(data = men, pop = pop, ages = 0:120, years = 1977:2019, type = "mortality")

# Create a StMoMoData object
mena <- StMoMoData(men_demogdata, series = "Male")

#Fit an LC model
LCfit <- fit(object = lc(),
             data = men,
             ages.fit = 0:120,
             years.fit = 1977 : 2019)

Any help or insights you can offer would be greatly appreciated!

Confirm that the men object has an entry for each year

Thank you for your reply, it indeed has an entry for each year for both objects men and pop which leaves me very puzzled

One of the basic and most important rules in this case remains to check that indeed each of your individual menobjects has been entered for the year. In this way, you will be able to solve or rather avoid the problem, which is the error concerning the number of years.

1 Like

Thanks for providing code. Could you kindly take further steps to make it easier for other forum users to help you? Share some representative data that will enable your code to run and show the problematic behaviour.

How do I share data for a reprex?

You might use tools such as the library datapasta, or the base function dput() to share a portion of data in code form, i.e. that can be copied from forum and pasted to R session.

Reprex Guide

Advice.
If your issue does not relate to file reading , i.e . You have no problem loading your raw data, your problem is manipulating/processing it, then you should modify your example to exclude all file loading code and substitute that code with example data that you prepared following the guide.

Thank you for you reply.

Here's a portion of my dataset, it still give the same error with this small sized data :

men <- data.frame(
years = c(1977, 1977, 1977, 1977, 1977),
ages = c(0, 1, 2, 3, 4),
Male = c(0.12771, 0.021871388, 0.0162858, 0.011811046, 0.008371515)
)

pop <- data.frame(
years = c(1977, 1977, 1977, 1977, 1977),
ages = c(0, 1, 2, 3, 4),
Male = c(1000, 1000, 1000, 1000, 1000)
)

1 Like

Yes, thank you. I have indeed checked all entries and there is no missing value.

This package would benefit greatly by improved documentation; the required data layout is not obvious but I think I figured it out; another tripping point was an apparent need for more than a single year of data.

library(StMoMo)
library(demography)
library(tidyverse)

men <- data.frame(
  years = c(1977, 1977, 1977, 1977, 1977),
  ages = c(0, 1, 2, 3, 4),
  Male = c(0.12771, 0.021871388, 0.0162858, 0.011811046, 0.008371515)
)
# need another year
men2 <- bind_rows(men,
                  mutate(men,
                         years=years+1))

pop <- data.frame(
  years = c(1977, 1977, 1977, 1977, 1977),
  ages = c(0, 1, 2, 3, 4),
  Male = c(1000, 1000, 1000, 1000, 1000)
)
# need another year
pop2 <- bind_rows(pop,
                  mutate(pop,
                         years=years+1))
# reorganise the data the way the functions seem to want
(pop3 <- pop2 |> pivot_wider(names_from = "years",values_from = "Male") )

pop4 <- select(pop3,-ages) |> as.data.frame()
rownames(pop4) <- pop3$ages



(men3 <- men2 |> pivot_wider(names_from = "years",values_from = "Male") )

men4 <- select(men3,-ages) |> as.data.frame()
rownames(men4) <- men3$ages


# Create a demogdata object
men_demogdata <- demogdata(data = men4, pop = pop4, ages = 0:4, years = 1977:1978, type = "mortality",label = "madeupplace",name="Male")

# Create a StMoMoData object
mena <- StMoMoData(men_demogdata, series = "Male")

#Fit an LC model
LCfit <- fit(object = lc(),
             data = mena,
             ages.fit = 0:4,
             years.fit = 1977:1978 )
2 Likes

What he said. Sometimes, I run across situations like these and I call them secret handshake clubs because they implicitly assume jdomain conventions that "everyone knows." Except newcomers.

1 Like

This topic was automatically closed 21 days after the last reply. New replies are no longer allowed.

If you have a query related to it or one of the replies, start a new topic and refer back with a link.