# 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
          summary[j,5]<-df[i,7]
        }
        
        # If this is the first chocolate of the box, copy box opened time to the summary
        if (df[i,3]==1) summary[j,4]<-df[i,5]
      }
    }
  }
  
  # 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

survival<-chocolateData$TimeEat-chocolateData$BoxPlace

# Bind survival time column to data frame

chocolateData<-cbind(chocolateData,SurvivalTime=survival)

# Update Leftover times
# Loop through each row of chocolateData and if Eaten="Leftover" then set SurvivalTime=NA

for (i in seq(length(chocolateData$Location)))
{
  if (chocolateData[i,8]=="Leftover") chocolateData[i,9]<-NA
}

