# Chocolate Data 4 - Convert times ### 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) } # timeToString - converts number of minutes # 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) # Create a vector boxOpened boxOpened<-c(NA,NA,NA,NA,NA,NA,NA,NA) # Create a vector finalSweet finalSweet<-c(NA,NA,NA,NA,NA,NA,NA,NA) # Bind the five vectors into a data frame called summary summary<-data.frame(Hospital=hospitals, Chocolates=chocolates, Eaten=numberEaten, BoxOpened=boxOpened, FinalSweet=finalSweet) # Loop through each record in the df data frame for (i in seq(1:length(df$Location))) { # For each row of the summary table... for(j in 1:8) { # ... check to see which row of the summary table it refers to if (df[i,1]==summary[j,1] && df[i,2]==summary[j,2]) { # If the chocolate has been eaten, increment the chocolates eaten counter # then transfer the time eaten to the summary file (this will be overwritten # by chocolates eaten after it). if (df[i,8]=="Eaten") { summary[j,3]<-summary[j,3]+1 } # If this is the first chocolate of the box, copy box opened time to the summary } } } # Return the completed summary data frame to the main script return(summary) } # convertToMinutes - 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, integer column # Returns: an integer representing minutes since midnight convertToMinutes<-function(x, column) { # Extract the string to be converted convertable<-as.vector(x[column]) # 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) } ### 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 convertToMinutes # to the data frame chocolateData # As convertToMinutes expects more than one parameter, # we have to prefix if with function(x) in the apply() boxPlaced<-apply(chocolateData,1,function(x) convertToMinutes(x,5)) # Replace the chocolateData$boxPlace with the new # minutes-only data now stored in the boxPlaced vector chocolateData$BoxPlace<-boxPlaced # Create a vector timeOpened by applying convertToMinutes # to the data frame chocolateData # As convertToMinutes expects more than one parameter, # we have to prefix if with function(x) in the apply() timeOpened<-apply(chocolateData,1,function(x) convertToMinutes(x,6)) # Replace the chocolateData$TimeOpen with the new # minutes-only data now stored in the timeOpened vector chocolateData$TimeOpen<-timeOpened # Create a vector timeEaten by applying convertToMinutes # to the data frame chocolateData # As convertToMinutes expects more than one parameter, # we have to prefix if with function(x) in the apply() timeEaten<-apply(chocolateData,1,function(x) convertToMinutes(x,7)) # Replace the chocolateData$boxPlace with the new # minutes-only data now stored in the timeEaten vector chocolateData$TimeEat<-timeEaten # Survival time = $TimeEat-$BoxPlace # Bind survival time column to data frame # Update Leftover times # Loop through each row of chocolateData and if Eaten="Leftover" then set SurvivalTime=NA