Automating data entry

Inserting explicit death subrecords

Sometimes individuals are defined with a date of birth but no death subrecord because there is no information about the death to warrant creating one. However, including an empty death subrecord is valuable in its own right to indicate the individual is dead. The insert_explicit_death_subrecords() function allows you to automatically insert these subrecords for individuals who would be too old to still be alive.

We illustrate with the following example of five individuals with various dates of birth (including a missing birth subrecord for person 5):

library(tidyged)
library(tidyged.utils)

people <- gedcom(subm("Me")) |> 
  add_indi(qn = "Person 1") |> 
  add_indi_fact("birth", date = date_calendar(1900, 4, 4)) |> 
  add_indi(qn = "Person 2") |> 
  add_indi_fact("birth", date = date_calendar(1888)) |>
  add_indi(qn = "Person 3") |> 
  add_indi_fact("birth", date = date_calendar(1885, 6)) |>
  add_indi(qn = "Person 4") |> 
  add_indi_fact("birth", date = date_calendar(1910)) |>
  add_indi(qn = "Person 5") |> 
  add_indi_fact("census", date = date_calendar(1911), age = "42y")
#> Added Unknown Individual: @I1@
#> Added Unknown Individual: @I2@
#> Added Unknown Individual: @I3@
#> Added Unknown Individual: @I4@
#> Added Unknown Individual: @I5@

dplyr::filter(people, tag == "DEAT")
#> # A tibble: 0 × 4
#> # ℹ 4 variables: level <dbl>, record <chr>, tag <chr>, value <chr>

If we were to assume a maximum age of 120 years (the default for the function) we would want a death subrecord for the first three individuals.

people_wds <- insert_explicit_death_subrecords(people, max_age = 120)

dplyr::filter(people_wds, tag == "DEAT")
#> # A tibble: 3 × 4
#>   level record tag   value
#>   <dbl> <chr>  <chr> <chr>
#> 1     1 @I1@   DEAT  ""   
#> 2     1 @I2@   DEAT  ""   
#> 3     1 @I3@   DEAT  ""

If an individual has no date of birth defined, then the default action is to leave the record as is. However, setting the guess parameter to TRUE will cause the function to guess an age from associated facts if a date of birth does not exist.

people_wds <- insert_explicit_death_subrecords(people, max_age = 120, guess = TRUE)

dplyr::filter(people_wds, tag == "DEAT")
#> # A tibble: 4 × 4
#>   level record tag   value
#>   <dbl> <chr>  <chr> <chr>
#> 1     1 @I1@   DEAT  ""   
#> 2     1 @I2@   DEAT  ""   
#> 3     1 @I3@   DEAT  ""   
#> 4     1 @I5@   DEAT  ""

We can now see an additional death subrecord for the fifth individual as the function has guessed the current age of the individual from the census event.

Inserting explicit marriage types

The GEDCOM specification recommends that all relationship events have an explicit TYPE subrecord. If one is not given, marriage is assumed. The insert_explicit_marr_types_all() function inserts an explicit marriage TYPE if one is not given:

dplyr::filter(sample555, record == "@F1@")
#> # A tibble: 7 × 4
#>   level record tag   value                                                      
#>   <dbl> <chr>  <chr> <chr>                                                      
#> 1     0 @F1@   FAM   ""                                                         
#> 2     1 @F1@   HUSB  "@I1@"                                                     
#> 3     1 @F1@   WIFE  "@I2@"                                                     
#> 4     1 @F1@   CHIL  "@I3@"                                                     
#> 5     1 @F1@   MARR  ""                                                         
#> 6     2 @F1@   DATE  "DEC 1859"                                                 
#> 7     2 @F1@   PLAC  "Rapid City, Pennington, South Dakota, United States of Am…

insert_explicit_marr_types_all(sample555) |> 
  dplyr::filter(record == "@F1@")
#> # A tibble: 8 × 4
#>   level record tag   value                                                      
#>   <dbl> <chr>  <chr> <chr>                                                      
#> 1     0 @F1@   FAM   ""                                                         
#> 2     1 @F1@   HUSB  "@I1@"                                                     
#> 3     1 @F1@   WIFE  "@I2@"                                                     
#> 4     1 @F1@   CHIL  "@I3@"                                                     
#> 5     1 @F1@   MARR  ""                                                         
#> 6     2 @F1@   TYPE  "marriage"                                                 
#> 7     2 @F1@   DATE  "DEC 1859"                                                 
#> 8     2 @F1@   PLAC  "Rapid City, Pennington, South Dakota, United States of Am…

Creating parent/ancestor placeholders

If you are visualising your tree and would like to automatically create ancestor records going back a certain number of generations, you can use the add_ancestors() function:

people_with_anc <- add_ancestors(people, "@I1@", num_gen = 2)
#> Added Family Group: @F1@
#> Added Male Individual: @I6@
#> Added Female Individual: @I7@
#> Added Family Group: @F2@
#> Added Male Individual: @I8@
#> Added Female Individual: @I9@
#> Added Family Group: @F3@
#> Added Male Individual: @I10@
#> Added Female Individual: @I11@

tidyged::describe_records(people_with_anc, people_with_anc$record)
#>  [1] "Submitter @U1@, Me"                                                
#>  [2] "Individual @I1@, Person 1, child of @I6@ and @I7@, born 4 APR 1900"
#>  [3] "Individual @I2@, Person 2, born 1888"                              
#>  [4] "Individual @I3@, Person 3, born JUN 1885"                          
#>  [5] "Individual @I4@, Person 4, born 1910"                              
#>  [6] "Individual @I5@, Person 5"                                         
#>  [7] "Family @F1@, headed by @I6@ and @I7@, and children: Person 1"      
#>  [8] "Individual @I6@, Unnamed individual, child of @I8@ and @I9@"       
#>  [9] "Individual @I7@, Unnamed individual, child of @I10@ and @I11@"     
#> [10] "Family @F2@, headed by @I8@ and @I9@, and children: @I6@"          
#> [11] "Individual @I8@, Unnamed individual"                               
#> [12] "Individual @I9@, Unnamed individual"                               
#> [13] "Family @F3@, headed by @I10@ and @I11@, and children: @I7@"        
#> [14] "Individual @I10@, Unnamed individual"                              
#> [15] "Individual @I11@, Unnamed individual"

In the example above, you can see it has created parents and grandparents for Person 1, and has also created the Family Group records since they didn’t already exist.

By default, the function will automatically assign the appropriate sex for new Individual records it creates:

dplyr::filter(people_with_anc, record %in% paste0("@I", 6:11, "@"), tag == "SEX")
#> # A tibble: 6 × 4
#>   level record tag   value
#>   <dbl> <chr>  <chr> <chr>
#> 1     1 @I6@   SEX   M    
#> 2     1 @I7@   SEX   F    
#> 3     1 @I8@   SEX   M    
#> 4     1 @I9@   SEX   F    
#> 5     1 @I10@  SEX   M    
#> 6     1 @I11@  SEX   F

If the inc_sex parameter is FALSE or if the function cannot determine the appropriate sex, it will set it to be undetermined:

add_ancestors(people, "@I1@", num_gen = 2, inc_sex = FALSE) |>
  dplyr::filter(record %in% paste0("@I", 6:11, "@"), tag == "SEX")
#> Added Family Group: @F1@
#> Added Unknown Individual: @I6@
#> Added Unknown Individual: @I7@
#> Added Family Group: @F2@
#> Added Unknown Individual: @I8@
#> Added Unknown Individual: @I9@
#> Added Family Group: @F3@
#> Added Unknown Individual: @I10@
#> Added Unknown Individual: @I11@
#> # A tibble: 6 × 4
#>   level record tag   value
#>   <dbl> <chr>  <chr> <chr>
#> 1     1 @I6@   SEX   U    
#> 2     1 @I7@   SEX   U    
#> 3     1 @I8@   SEX   U    
#> 4     1 @I9@   SEX   U    
#> 5     1 @I10@  SEX   U    
#> 6     1 @I11@  SEX   U

The add_parents() function is equivalent to running add_ancestors() with num_gen = 1.