# Chocolate Data - 16-2 - Exercise 1 ### Function Definitions # updateToFactor - Converts the numeric column to a factor # Data frame column dfc and list of replacement values v passed to function # Returns the factor form of the data column updateToFactor<-function(dfc,v) { # dfc is currently a numeric vector # We want to generate a character vector, so create a new NULL vector # that can have the appropriate elements added to it newValues<-NULL # Loop through each element of dfc and add the appropriate value # from v to the end of newValues to get a vector of characters that is # the same length as the original dfc column for(i in dfc) { newValues<-c(newValues,v[i]) } # Convert newValues to a factor newValues<-factor(newValues) # Return newValues return(newValues) } # updateToFactor - Converts the numeric column to a factor # Data frame column dfc and list of replacement values v passed to function # Returns the factor form of the data column updateCodeToFactor<-function(dfc,v) { # dfc is currently a numeric vector # We want to generate a character vector, so create a new NULL vector # that can have the appropriate elements added to it newValues<-NULL # Loop through each element of dfc and add the appropriate value # from v to the end of newValues to get a vector of characters that is # the same length as the original dfc column # This is not the most elegant way of doing this, but it's the easiest # The original Excel file gives an incorrect set of codes - # HA should be HCA and P should be PT for(i in dfc) { if (i=="A") newValues<-c(newValues,v[1]) if (i=="D") newValues<-c(newValues,v[2]) if (i=="HCA") newValues<-c(newValues,v[3]) if (i=="N") newValues<-c(newValues,v[4]) if (i=="OT") newValues<-c(newValues,v[5]) if (i=="PT") newValues<-c(newValues,v[6]) if (i=="O") newValues<-c(newValues,v[7]) if (i=="Leftover") newValues<-c(newValues,v[8]) } # Convert newValues to a factor newValues<-factor(newValues) # Return newValues return(newValues) } # generateSummary - Counts how many of each chocolate were eaten where # Creates a data frame to record the sweets eaten in each location # Data frame df passed to function # Returns the data frame # This needs a data frame that contains 8 rows and 3 columns # Column 1 - each hospital name twice # Column 2 - each chocolate brand for each hospital # Column 3 - the number of chocolates of that brand eaten at that hospital generateSummary<-function(df) { # Create a vector hospitals containing the hospital names hospitals<-c("Bedford AAU", "Bedford AAU", "Bedford Pilgrim","Bedford Pilgrim", "Swindon Meldon","Swindon Meldon", "UHNS Haem","UHNS Haem") # Create a vector chocolates containing the chocolate brands chocolates<-c("Roses","Quality Street","Roses","Quality Street", "Roses","Quality Street","Roses","Quality Street") # Create a vector numberEaten containing zeros (to be updated) numberEaten<-c(0,0,0,0,0,0,0,0) # Bind the three vectors into a data frame called summary summary<-data.frame(Hospital=hospitals, Chocolates=chocolates, Eaten=numberEaten) # Loop through each record in the df data frame for (i in seq(1:length(df$Location))) { # Check which hospital name and chocolate brand the line refers to # If the chocolate is "Eaten" then update the appropriate entry # in the summary table (8 IF statements, one per line of summary) if (df[i,1]==summary[1,1] && df[i,8]=="Eaten" && df[i,2]==summary[1,2]) summary[1,3]<-summary[1,3]+1 if (df[i,1]==summary[2,1] && df[i,8]=="Eaten" && df[i,2]==summary[2,2]) summary[2,3]<-summary[2,3]+1 if (df[i,1]==summary[3,1] && df[i,8]=="Eaten" && df[i,2]==summary[3,2]) summary[3,3]<-summary[3,3]+1 if (df[i,1]==summary[4,1] && df[i,8]=="Eaten" && df[i,2]==summary[4,2]) summary[4,3]<-summary[4,3]+1 if (df[i,1]==summary[5,1] && df[i,8]=="Eaten" && df[i,2]==summary[5,2]) summary[5,3]<-summary[5,3]+1 if (df[i,1]==summary[6,1] && df[i,8]=="Eaten" && df[i,2]==summary[6,2]) summary[6,3]<-summary[6,3]+1 if (df[i,1]==summary[7,1] && df[i,8]=="Eaten" && df[i,2]==summary[7,2]) summary[7,3]<-summary[7,3]+1 if (df[i,1]==summary[8,1] && df[i,8]=="Eaten" && df[i,2]==summary[8,2]) summary[8,3]<-summary[8,3]+1 } # Return the completed summary data frame to the main script return(summary) } # convertBoxPlaceToMinutes - Takes a "HH:MM" string and converts # it to an integer number of minutes (O0:00 is 0 minutes) # Parameters passed: data frame row x # Returns: an integer representing minutes since midnight convertBoxPlaceToMinutes<-function(x) { # Extract the string to be converted # BoxPlace is column 5 convertable<-as.vector(x[5]) # Some strings are 4 characters, some are 5 # The number of characters to the left of the # colon is 1 if the number is 4, 2 if it is 5 # Use the function nchar(string) to get the # the string length stringlength<-nchar(convertable) # If stringlength is 4 # hours is character 1 * 60 # minutes is characters 3,4 # minuteTime is hours+minutes # Use the function substr(x,start,stop) # to get the substrings, then as.numeric() if(stringlength==4) { hours<-as.numeric(substr(convertable,1,1))*60 minutes<-as.numeric(substr(convertable,3,4)) minuteTime<-hours+minutes } # If stringlength is 5 # hours is characters 1,2 * 60 # minutes is characters 4,5 # minuteTime is hours+minutes # Use the function substr(x,start,stop) # to get the substrings, then as.numeric() if(stringlength==5) { hours<-as.numeric(substr(convertable,1,2))*60 minutes<-as.numeric(substr(convertable,4,5)) minuteTime<-hours+minutes } # Return the value of minuteTime return(minuteTime) } # convertTimeOpenedToMinutes - Takes a "HH:MM" string and converts # it to an integer number of minutes (O0:00 is 0 minutes) # Parameters passed: data frame row x # Returns: an integer representing minutes since midnight convertTimeOpenedToMinutes<-function(x) { # Extract the string to be converted # TimeOpened is column 6 # Some strings are 4 characters, some are 5 # The number of characters to the left of the # colon is 1 if the number is 4, 2 if it is 5 # Use the function nchar(string) to get the # the string length # If stringlength is 4 # hours is character 1 * 60 # minutes is characters 3,4 # minuteTime is hours+minutes # Use the function substr(x,start,stop) # to get the substrings, then as.numeric() # If stringlength is 5 # hours is characters 1,2 * 60 # minutes is characters 4,5 # minuteTime is hours+minutes # Use the function substr(x,start,stop) # to get the substrings, then as.numeric() # Return the value of minuteTime } # convertTimeEatToMinutes - Takes a "HH:MM" string and converts # it to an integer number of minutes (O0:00 is 0 minutes) # Parameters passed: data frame row x # Returns: an integer representing minutes since midnight convertTimeEatenToMinutes<-function(x) { # Extract the string to be converted # BoxPlace is column 7 # Some strings are 4 characters, some are 5 # The number of characters to the left of the # colon is 1 if the number is 4, 2 if it is 5 # Use the function nchar(string) to get the # the string length # If stringlength is 4 # hours is character 1 * 60 # minutes is characters 3,4 # minuteTime is hours+minutes # Use the function substr(x,start,stop) # to get the substrings, then as.numeric() # If stringlength is 5 # hours is characters 1,2 * 60 # minutes is characters 4,5 # minuteTime is hours+minutes # Use the function substr(x,start,stop) # to get the substrings, then as.numeric() # Return the value of minuteTime } ### Main Script # Load data file into data frame ChocolateData # We want to work with categorical data, so use stringsAsFactors=TRUE chocolateData<-read.csv("SP16/ChocolateDataCSV.csv", header=TRUE, stringsAsFactors = FALSE) # Update WhoAte to become a factor # Define the values to replace the numbers in the column to be factorised newValues<-c("Administrative","Doctor","Healthcare Assistant","Nurse", "Occupational Therapist","Physiotherapist","Other","Not Eaten") # Call updateCodeToFactor with WhoAte and newValues chocolateData$WhoAte<-updateCodeToFactor(chocolateData$WhoAte,newValues) # Update Location to become a factor # Define the values to replace the numbers in the column to be factorised newValues<-c("Bedford AAU","Bedford Pilgrim","Swindon Meldon","UHNS Haem") # Call updateToFactor with Location and newValues chocolateData$Location<-updateToFactor(chocolateData$Location,newValues) # Define the values to replace the numbers in the column to be factorised newValues<-c("Roses","Quality Street") # The $Chocolate column starts at 0, not 1, so needs to be updated # Add 1 to every element in chocolateData$Chocolate chocolateData$Chocolate<-chocolateData$Chocolate+1 # Call updateToFactor with $Chocolate and newValues chocolateData$Chocolate<-updateToFactor(chocolateData$Chocolate,newValues) # Define the values to replace the numbers in the column to be factorised newValues<-c("Leftover","Eaten") # The $Eaten column starts at 0, not 1, so needs to be updated # Add 1 to every element in chocolateData$Eaten chocolateData$Eaten<-chocolateData$Eaten+1 # Call updateToFactor with $Eaten and newValues chocolateData$Eaten<-updateToFactor(chocolateData$Eaten,newValues) # Generate summary summary<-generateSummary(chocolateData) # Display the summary data summary # Create a vector boxPlaced by applying # convertBoxPlaceToMinutes to the data frame chocolateData boxPlaced<-apply(chocolateData,1,convertBoxPlaceToMinutes) # Replace the chocolateData$boxPlace with the new # minutes-only data now stored in the boxPlaced vector chocolateData$BoxPlace<-boxPlaced # Create a vector timeOpen by applying # convertTimeOpenedToMinutes to the data frame chocolateData # Replace the chocolateData$TimeOpen with the new # minutes-only data now stored in the timeOpen vector # Create a vector timeEaten by applying # convertTimeEatenToMinutes to the data frame chocolateData # Replace the chocolateData$TimeEat with the new # minutes-only data now stored in the timeEaten vector