Create Data for exercise:
In our case i generated name for the data.
These are people who are either members of the family or friends who are invited to go to a wedding. The couple want to see which people from this large set of people are related to each other.
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