Search code examples
csvnetlogoagent-based-modelingdemographics

error applying an age distribution from csv file


I just discovered an error in my model where I create a population with a household-size distribution and dependent age distribution. My problem is that my procedure doesn't seem to assign the probabilities for each outcome correctly when deciding the age. I am supposed to have 16% elderly but my model gives me 3% (of tot population).

I think this has to do with the internal order of the procedure, as elderly are assigned last. See below code.

Procedure for assigning household-size:

to hatch-family ; hatching the rest of the household using percentual distribution of household size in berlin population
  ifelse random-float 1 <= 0.01 [set household-size 6  set dwelling patch-here hatch 5]
  [ifelse random-float 1 <= 0.02 [set household-size 5 set dwelling patch-here hatch 4]
    [ifelse random-float 1 <= 0.06 [set household-size 4  set dwelling patch-here hatch 3]
      [ifelse random-float 1 <= 0.11 [set household-size 3 set dwelling patch-here hatch 2]
        [ifelse random-float 1 <= 0.31 [set household-size 2 set dwelling patch-here hatch 1]
          [ifelse random-float 1 <= 0.49 [set household-size 1 set dwelling patch-here]
          [hatch-family]
  ]]]]]
end

Procedure for assigning age:

to assign-age; assign age depending on household size according to distribution on csv file,
             ;i = the different rows representing different household sizes
  get-age-data
  if household-size = 1 [get-age-breed 1]
  if household-size = 2 [get-age-breed 2]
  if household-size = 3 [get-age-breed 3]
  if household-size = 4 [get-age-breed 4]
  if household-size = 5 [get-age-breed 5]
  if household-size = 6 [get-age-breed 6]
end

to get-age-data ; reading csv file and creating dataset with age distribution of the population
  file-close-all                          ; close all open files
    if not file-exists? "Data/age-dist-breeds.csv"  [
    user-message "No file 'age-dist-breeds' exists!"
    stop
  ]

  file-open "Data/age-dist-breeds.csv"  ; open the file with the turtle data
  set age-data csv:from-file "Data/age-dist-breeds.csv"
  file-close                              ; making sure to close the file
end

to get-age-breed [i]; process for assigning age after distribution for household size i, will repeat itself if no age is assigned in previous run
  let child-var item 1 item i age-data
ifelse (random-float 1 <= child-var)
   [set age random 14 set breed children set age-susceptibility 0.0025]
   [let teen-var item 2 (item i age-data)
     ifelse (random-float 1 <= teen-var)
    [set age 15 + random 4 set breed teens set age-susceptibility 0.005]
    [let adult-var item 3 (item i age-data)
        ifelse ( random-float 1 <= adult-var)
           [let age-susc-var random 49
            set age 20 + age-susc-var set breed adults set age-susceptibility (age-susc-var / 49) * 0.075 + 0.015]
           [let elder-var item 4 (item i age-data)
  ifelse ( random-float 1 <= elder-var )
        [ set age 70 + random 30 set breed elderly set age-susceptibility 0.08]
        [get-age-breed i]
    ]]
  ]
end

I tried to make a random-var at the beginning instead of recalculating it for each step but then I ended up with no elderly whatsoever.

Is there a better way than the random-float procedure to accurately assign non-normal probability distributions?


Solution

  • I finally solved it with some input from @JenB.

    The code now looks as follows:

    Procedure for hatching the rest of the households according to -accumulative- household-size distribution:

    ; hatching the rest of the household using percentual distribution of household size of Berlin population (Zensus Datenbank)
    ; (nr of households with specific size / total number of households in Berlin, 
    ; hence the percentage of the total population will be accurate as the population increases with each hatching)
    to hatch-family
    ask turtles
      [ 
      let my-draw random-float 1
      (ifelse
       my-draw <= 0.01 [set household-size 6 set dwelling patch-here hatch 5]
       my-draw <= 0.03 [set household-size 5 set dwelling patch-here hatch 4]
       my-draw <= 0.09 [set household-size 4 set dwelling patch-here hatch 3]
       my-draw <= 0.20 [set household-size 3 set dwelling patch-here hatch 2]
       my-draw <= 0.51 [set household-size 2 set dwelling patch-here hatch 1]
          my-draw <= 1 [set household-size 1 set dwelling patch-here]
        )
      ]
    end
    

    Procedure for assigning breed and age depending on distributions of age for each household-size:

    (This one I solved with up-to-n-of command instead of random-float to address the problem with the probabilities not always being in order of lowest->highest)

    to assign-age; assign age depending on household size according to distribution on csv file,
                 ;second item [i] = the different rows representing different household sizes
      ask turtles [set age 0]
      get-age-data ; reading csv file and naming it age-data
      get-age-breed 1
      get-age-breed 2
      get-age-breed 3
      get-age-breed 4
      get-age-breed 5
      get-age-breed 6
    end
    
    to get-age-breed [i]; process for assigning age after distribution for household size i
      let child-var up-to-n-of ((count turtles with [household-size = i]) * item 1 (item i age-data)) (turtles with [household-size = i and age = 0])
      ask child-var [set age random 14 set breed children set age-susceptibility 0.0025]
      let teen-var up-to-n-of (count turtles with [household-size = i] * item 2 item i age-data) (turtles with [household-size = i and age = 0])
      ask teen-var [set age 15 + random 4 set breed teens set age-susceptibility 0.005]
      let elder-var up-to-n-of (count turtles with [household-size = i] * item 4 item i age-data) (turtles with [household-size = i and age = 0])
      ask elder-var [set age 70 + random 30 set breed elderly set age-susceptibility 0.08]
      let adult-var up-to-n-of (count turtles with [household-size = i] * item 3 item i age-data) (turtles with [household-size = i and age = 0])
      ask adult-var [let age-susc-var random 49 set age 20 + age-susc-var set breed adults set age-susceptibility (age-susc-var / 49) * 0.075 + 0.015]
     
    end