Create Data for exercise:

Assumption:

#create wedding list dataframe
wedding_list <- data.frame(
  family_code = c("A10", "B11", "C12", "D13", "E14", "F15", "G16"),
  mother_name = c("Amina", "Layla", "Aziza", "Layla", "Khadija", "Safiya", "Noor"),
  father_name = c("Bilal", "Yusuf", "Kalide", "Emran", "Emran", "Adam", "Bilal")
)

wedding_list
##   family_code mother_name father_name
## 1         A10       Amina       Bilal
## 2         B11       Layla       Yusuf
## 3         C12       Aziza      Kalide
## 4         D13       Layla       Emran
## 5         E14     Khadija       Emran
## 6         F15      Safiya        Adam
## 7         G16        Noor       Bilal

#——————— Creating Algorithm

Need a function that can find the relationship within the wedding list and assign a relation code for mapping. #———————

#load package
library(dplyr)

#Creating a function that starts with the first family unit and extract the names and family code.
#We then find anyone who is associated to this group and assign this group a unique relation_code.
#We do this recursively until all families in the data table have been assigned a relation_code.
relation_code_func <- function(data) {
  #relational code: create the fourth column to our data table and assign NA for all families
  data$relational_code <- NA_character_
  
  #counter for the sequential relational code generator
  initial_number <- 1
  
  #if data$relational_code vector has any empty value, run a while loop
  while (any(is.na(data$relational_code))) {
    
    #sets both temporary list to empty
    names_in_group <- c()
    families_in_group <- c()
    
    #create an unassigned families table for families where relational_code is still missing
    unassigned_families <- data %>%
      filter(is.na(relational_code))
    
    #select the first family code to current_family as our seed
    current_family <- unassigned_families$family_code[1]
    
    #filter the data on current_family seed. Pull all members names from this family and their family code respectively
    current_record <- data %>%
      filter(family_code == current_family)
  
    names_in_group <- append(
      names_in_group, current_record$mother_name)
  
    names_in_group <- append(
      names_in_group, current_record$father_name)
  
    families_in_group <- append(
      families_in_group,current_record$family_code)
  
    #create a while 'TRUE' condition. Run a loop to find the rows that have the names from our names_in_group temp list
    new_connection_found <- TRUE
    
    while (new_connection_found) {
      #keep only rows where at least the mother_name or father_name exists in our temp. list.
      connected_records <- data %>%
        filter(
          mother_name %in% names_in_group |
          father_name %in% names_in_group
          )
      
      #filter rows in connected records, where the family code is not in temp. list. Expanding the related family list.
      new_relatives_tbl <- connected_records %>%
        filter(!(family_code %in% families_in_group))
      
      
      #when the family_code has relatives, append new family codes into temp. list.
      if(nrow(new_relatives_tbl) > 0) {
        families_in_group <- append(
        families_in_group, new_relatives_tbl$family_code
        )
        
        #expand names_in_group, by appending father and mother names to the temp. list when they don't exist
        add_new_names <- c(
        new_relatives_tbl$mother_name,
        new_relatives_tbl$father_name
        )
        add_new_names <- add_new_names[
        !(add_new_names%in% names_in_group)]
        names_in_group <- append(names_in_group, add_new_names)
        
      } else {
        #If no more new relatives (size of relatives table is 0), set a turn off while loop condition.
        new_connection_found <- FALSE
      }
      
      #assign a code to the families that are in our populated families_in_group list
    }
      #create a logical mask to see which family_codes exist in families_in_group
      rows_to_assign <- data$family_code %in% families_in_group
      
      #unmask, use sequential assignment for the family codes that exist in families_in_group only
      data[rows_to_assign, "relational_code"] <- 
        sprintf("R%03d", initial_number)
      
      #increment initial number post first loop
      initial_number <- initial_number + 1
      }
  
  #return the completed database
  return(data)
  }
#run function output and return results
results <- relation_code_func(wedding_list)

results
##   family_code mother_name father_name relational_code
## 1         A10       Amina       Bilal            R001
## 2         B11       Layla       Yusuf            R002
## 3         C12       Aziza      Kalide            R003
## 4         D13       Layla       Emran            R002
## 5         E14     Khadija       Emran            R002
## 6         F15      Safiya        Adam            R004
## 7         G16        Noor       Bilal            R001