From 333d6bf1363e8d45fddc86e993571e6755d7b28b Mon Sep 17 00:00:00 2001 From: Kelly Barnes Date: Wed, 8 Nov 2023 08:52:38 -0500 Subject: [PATCH 1/7] introduces scheduling groups fun --- R/instructor_training.R | 62 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 62 insertions(+) diff --git a/R/instructor_training.R b/R/instructor_training.R index ee433d0..761ebf4 100644 --- a/R/instructor_training.R +++ b/R/instructor_training.R @@ -139,6 +139,68 @@ map_timezones <- function(df) { return(df) } +#' Create Scheduling Groups +#' +#' +#' @param df Dataframe; The data frame containing timezone information. Comes from Trainer Quarterly Availability Form. +#' +#' @return Dataframe; The data frame with an additional 'sched_group' +#' column. +#' Throws an error if no matching column or multiple matching columns are found. +#' +#' @importFrom stringr str_detect +#' @importFrom dplyr rename mutate +#' @export +#' +#' @examples +#' \dontrun{ +#' # Assume 'data_with_timezones' is a data frame with an appropriate timezone column +#' grouped_timezones <- map_timezones(data_with_timezones) +#' print(grouped_timezones) +#' } +#' +map_scheduling_group <- function(df) { + # The regex pattern matches both spaces and dots + matching_cols <- + grepl( + "^What time zone are you located in", + names(df), + ignore.case = TRUE + ) + if (sum(matching_cols) > 1) { + stop("Error: Multiple matching columns found.") + } + if (sum(matching_cols) == 0) { + stop("No matching column name found.") + } + col_index <- which(matching_cols) + df <- df %>% + rename(timezone = names(df)[col_index]) + + df <- df %>% + mutate( + FD_ET = ifelse( + str_detect(timezone, "UTC[-]7|UTC[-]6|UTC[-]5|UTC[-]4|UTC[-]3|UTC[-]2[:]?30"), "FD_ET", NA), #EST +/- 2, also includes Newfoundland timezone + FD_PT = ifelse( + str_detect(timezone, "UTC[-]10|UTC[-]9|UTC[-]8|UTC[-]7|UTC[-]6"), "FD_PT", NA), # PST +/- 2 + FD_CET = ifelse( + str_detect(timezone, "UTC[-]1|UTC[ ]?0|UTC[+]1|UTC[+]2"), "FD_CET", NA), # CEST +/- 2 + FD_AET = ifelse( + str_detect(timezone, "UTC[+]12|UTC[+]11|UTC[+]10|UTC[+]9|UTC[+]8"), "FD_AET", NA), # AEST +/- 2 + HD_PM_PT = ifelse( + str_detect(timezone, "UTC[+]10|UTC[+]11|UTC[+]12|UTC[-]12|UTC[-]11|UTC[-]10|UTC[-]9|UTC[-]8|UTC[-]7|UTC[-]6"), "HD_PM_PT", NA), # PST + 6 hours before and 2 hours after + HD_PM_ET = ifelse( + str_detect(timezone, "UTC[-]11|UTC[-]10|UTC[-]9|UTC[-]8|UTC[-]7|UTC[-]6|UTC[-]5|UTC[-]4|UTC[-]3"), "HD_PM_ET", NA), + HD_PM_CET = ifelse( + str_detect(timezone, "UTC[-]5|UTC[-]4|UTC[-]3|UTC[-]2[:]?30|UTC[-]2|UTC[-]1|UTC[ ]?0|UTC[+]1|UTC[+]2|UTC[+]3"), "HD_PM_CET", NA), + HD_PM_AET = ifelse( + str_detect(timezone, "UTC[+]4|UTC[+]5|UTC[+]6|UTC[+]7|UTC[+]8|UTC[+]9|UTC[+]10|UTC[+]11|UTC[+]12"), "HD_PM_AET", NA) + ) + + + return(df) +} + #' Extract Quarter and Year Information from Data Frame Name #' #' This function extracts the quarter and year information from a given data frame name. From 0d2933b4a8096039c2ab817032b23019555526b8 Mon Sep 17 00:00:00 2001 From: Kelly Barnes Date: Fri, 10 Nov 2023 11:11:20 -0500 Subject: [PATCH 2/7] create load_libraries function --- DESCRIPTION | 2 ++ NAMESPACE | 3 +++ R/tools.R | 35 +++++++++++++++++++++++++++++++++++ man/load_libraries.Rd | 14 ++++++++++++++ 4 files changed, 54 insertions(+) create mode 100644 man/load_libraries.Rd diff --git a/DESCRIPTION b/DESCRIPTION index 8cad6ff..08d4771 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -12,10 +12,12 @@ Imports: stringr, ggplot2, airtabler, + paintbrush, lubridate, rlang Remotes: bergant/airtabler, + klbarnes20/paintbrush Encoding: UTF-8 Roxygen: list(markdown = TRUE) RoxygenNote: 7.2.3 diff --git a/NAMESPACE b/NAMESPACE index 0aeff55..abd71e3 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -9,6 +9,7 @@ export(calculate_dropout_rate) export(calculate_rate) export(calculate_reengagement_rate) export(calculate_wksurvey_item_mean) +export(clean_select_all_responses) export(count_trainings) export(count_trainings_rel_yr) export(count_trainings_yr) @@ -16,7 +17,9 @@ export(extract_year_quarter) export(fetch_airtable) export(fetch_redash) export(generate_plot) +export(load_libraries) export(map_availability) +export(map_scheduling_group) export(map_timezones) export(preprocess_trainee_data) export(save_plot) diff --git a/R/tools.R b/R/tools.R index 444698c..a73c942 100644 --- a/R/tools.R +++ b/R/tools.R @@ -48,3 +48,38 @@ set_time_frame <- function(dat, col, start, end) { return(df) } + +#' Clean Select All Survey Response Data +#' +#' @param dat +#' @param col +#' +#' @return +#' @export +#' +#' @examples +clean_select_all_responses <- function(dat, col) { + col_sym <- sym(col) + response_table <- data %>% + separate_rows(col_sym, sep = ",") %>% + mutate(col = str_trim(col)) %>% + count(col) + return(response_table) +} + +#' Load Libraries +#' +#' @param libraries +#' +#' @return +#' @export +#' +#' @examples +load_libraries <- function(libraries) { + for (lib in libraries) { + if (!require(lib, character.only = TRUE)) { + install.packages(lib) + library(lib, character.only = TRUE) + } + } +} diff --git a/man/load_libraries.Rd b/man/load_libraries.Rd new file mode 100644 index 0000000..f6002c4 --- /dev/null +++ b/man/load_libraries.Rd @@ -0,0 +1,14 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/tools.R +\name{load_libraries} +\alias{load_libraries} +\title{Load Libraries} +\usage{ +load_libraries(libraries) +} +\arguments{ +\item{libraries}{} +} +\description{ +Load Libraries +} From 5b119528313f563a7f940a520e08e1f168e994ef Mon Sep 17 00:00:00 2001 From: Kelly Barnes Date: Fri, 10 Nov 2023 12:05:17 -0500 Subject: [PATCH 3/7] adds calculate net promoter --- NAMESPACE | 1 + R/surveys.R | 44 ++++++++++++++++++++++++++++++++++++++++++++ man/calculate_nps.Rd | 14 ++++++++++++++ 3 files changed, 59 insertions(+) create mode 100644 R/surveys.R create mode 100644 man/calculate_nps.Rd diff --git a/NAMESPACE b/NAMESPACE index abd71e3..fe9432d 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -6,6 +6,7 @@ export(calculate_checkout_not_finished) export(calculate_checkout_rate) export(calculate_checkout_started) export(calculate_dropout_rate) +export(calculate_nps) export(calculate_rate) export(calculate_reengagement_rate) export(calculate_wksurvey_item_mean) diff --git a/R/surveys.R b/R/surveys.R new file mode 100644 index 0000000..9e5c802 --- /dev/null +++ b/R/surveys.R @@ -0,0 +1,44 @@ + + +#' Calculate Net Promoter Score +#' +#' #'How to calculate net promoter score: https://monkeylear.com/blog/nps-analysis/ +#' +#' @param dat +#' @param col +#' +#' @return +#' @export +#' + +#' +#' @examples +calculate_nps <- function(dat, col) { + # Ensure col is a character vector of length 1 + if (!is.character(col) || length(col) != 1) { + stop("Error: 'col' should be a single column name as character.") + } + + # Check in the column exists in the data frame + if (!col %in% names(dat)) { + stop("Error: Specified column does not exist in the data frame.") + } + + # Check if hte dat in the column is numeric + if (!is.numeric(dat[[col]])) { + stop("Error: Data in the specified column is not numeric.") + } + # Calculate net promoter score + table <- dat %>% + mutate(Category = case_when( + .[[col]] <= 6 ~ 'Detractor', + .[[col]] %in% 7:8 ~ 'Passive', + .[[col]] >= 9 ~ 'Promoter', + TRUE ~ NA_character_ + )) %>% + filter(!is.na(Category)) %>% + group_by(Category) %>% + summarise(Number = n(), .groups = 'drop') %>% + mutate(Percent = (Number / sum(Number))) + +} diff --git a/man/calculate_nps.Rd b/man/calculate_nps.Rd new file mode 100644 index 0000000..30fcb9b --- /dev/null +++ b/man/calculate_nps.Rd @@ -0,0 +1,14 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/surveys.R +\name{calculate_nps} +\alias{calculate_nps} +\title{Calculate Net Promoter Score} +\usage{ +calculate_nps(dat, col) +} +\arguments{ +\item{col}{} +} +\description{ +#'How to calculate net promoter score: https://monkeylear.com/blog/nps-analysis/ +} From 5b7c43916c36991178dac9f4490b8fb2f8527f74 Mon Sep 17 00:00:00 2001 From: Kelly Barnes Date: Fri, 10 Nov 2023 14:17:09 -0500 Subject: [PATCH 4/7] adds new plot functions --- NAMESPACE | 5 ++++ R/plotting.R | 53 ++++++++++++++++++++++++++++++++++ man/add_text_geom.Rd | 20 +++++++++++++ man/custom_scale_x_discrete.Rd | 14 +++++++++ man/percent_label.Rd | 14 +++++++++ 5 files changed, 106 insertions(+) create mode 100644 man/add_text_geom.Rd create mode 100644 man/custom_scale_x_discrete.Rd create mode 100644 man/percent_label.Rd diff --git a/NAMESPACE b/NAMESPACE index fe9432d..42b163f 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -1,5 +1,6 @@ # Generated by roxygen2: do not edit by hand +export(add_text_geom) export(badged_n_days) export(calculate_avg_time_to_checkout) export(calculate_checkout_not_finished) @@ -14,14 +15,18 @@ export(clean_select_all_responses) export(count_trainings) export(count_trainings_rel_yr) export(count_trainings_yr) +export(custom_scale_x_discrete) export(extract_year_quarter) export(fetch_airtable) export(fetch_redash) +export(gather_and_summarise) export(generate_plot) +export(group_by_summarise) export(load_libraries) export(map_availability) export(map_scheduling_group) export(map_timezones) +export(percent_label) export(preprocess_trainee_data) export(save_plot) export(set_time_frame) diff --git a/R/plotting.R b/R/plotting.R index 4b5fa38..7b6dd1c 100644 --- a/R/plotting.R +++ b/R/plotting.R @@ -57,3 +57,56 @@ save_plot <- function(dir, plot) { print(path) ggsave(path, plot = plot, device = 'png', dpi = 300, width = 4, height = 3) } + +#' Add Data Labels to Plot +#' +#' @param label_type +#' @param accuracy +#' @param color +#' @param vjust +#' @param fontface +#' +#' @return +#' @export +#' +#' @examples +add_text_geom <- function(label_type = "count", accuracy = 0.1, color = "white", vjust = 1.6, fontface = "bold") { + if (label_type == "count") { + plot + geom_text(aes(label = count), color = color, vjust = vjust, fontface = fontface) + } else if (label_type == "percent") { + geom_text(aes(label = scales::label_percent(accuracy = accuracy)(percent)), color = color, vjust = vjust, fontface = fontface) + } +} + +#' Format and Text Wrap X Axis Labels +#' +#' @param labels +#' @param wrap_width +#' +#' @return +#' @export +#' +#' @examples +custom_scale_x_discrete <- function(labels, wrap_width = 15) { + scale_x_discrete( + drop = FALSE, + labels = function(x) lapply( + strwrap(labels, width = wrap_width, simplify = FALSE), + paste, + collapse = "\n" + ) + ) +} + +#' Add Percent Sign to Data Label +#' +#' @param x +#' @param decimal +#' +#' @return +#' @export +#' +#' @examples +percent_label <- function(x, decimal = 1) { + paste0(round(x, decimal), "%") +} diff --git a/man/add_text_geom.Rd b/man/add_text_geom.Rd new file mode 100644 index 0000000..d614256 --- /dev/null +++ b/man/add_text_geom.Rd @@ -0,0 +1,20 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/plotting.R +\name{add_text_geom} +\alias{add_text_geom} +\title{Add Data Labels to Plot} +\usage{ +add_text_geom( + label_type = "count", + accuracy = 0.1, + color = "white", + vjust = 1.6, + fontface = "bold" +) +} +\arguments{ +\item{fontface}{} +} +\description{ +Add Data Labels to Plot +} diff --git a/man/custom_scale_x_discrete.Rd b/man/custom_scale_x_discrete.Rd new file mode 100644 index 0000000..148451f --- /dev/null +++ b/man/custom_scale_x_discrete.Rd @@ -0,0 +1,14 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/plotting.R +\name{custom_scale_x_discrete} +\alias{custom_scale_x_discrete} +\title{Format and Text Wrap X Axis Labels} +\usage{ +custom_scale_x_discrete(labels, wrap_width = 15) +} +\arguments{ +\item{wrap_width}{} +} +\description{ +Format and Text Wrap X Axis Labels +} diff --git a/man/percent_label.Rd b/man/percent_label.Rd new file mode 100644 index 0000000..613441e --- /dev/null +++ b/man/percent_label.Rd @@ -0,0 +1,14 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/plotting.R +\name{percent_label} +\alias{percent_label} +\title{Add Percent Sign to Data Label} +\usage{ +percent_label(x, decimal = 1) +} +\arguments{ +\item{decimal}{} +} +\description{ +Add Percent Sign to Data Label +} From da57e2ae1b5af4911152d90c5b00a2aecd4dd0db Mon Sep 17 00:00:00 2001 From: Kelly Barnes Date: Fri, 10 Nov 2023 14:17:32 -0500 Subject: [PATCH 5/7] adds new data manipulation funs --- R/surveys.R | 40 +++++++++++++++++++++++++++++++ R/tools.R | 28 ++++++++++++++++++++++ man/clean_select_all_responses.Rd | 14 +++++++++++ man/gather_and_summarise.Rd | 14 +++++++++++ man/group_by_summarise.Rd | 14 +++++++++++ man/map_scheduling_group.Rd | 27 +++++++++++++++++++++ 6 files changed, 137 insertions(+) create mode 100644 man/clean_select_all_responses.Rd create mode 100644 man/gather_and_summarise.Rd create mode 100644 man/group_by_summarise.Rd create mode 100644 man/map_scheduling_group.Rd diff --git a/R/surveys.R b/R/surveys.R index 9e5c802..81e1521 100644 --- a/R/surveys.R +++ b/R/surveys.R @@ -42,3 +42,43 @@ calculate_nps <- function(dat, col) { mutate(Percent = (Number / sum(Number))) } + +#' Gather Questions into One Table to Graph Together +#' +#' @param dat +#' @param questions +#' @param levels +#' @param labels +#' +#' @return +#' @export +#' +#' @examples +gather_and_summarise <- function(dat, questions, levels, labels){ + # Validation Checks + if (!is.data.frame(dat)) { + stop("Error: 'dat' should be a data frame.") + } + + if (!all(questions %in% names(dat))) { + stop("Error: Some questions in 'questions' are not column names in 'dat'.") + } + + if (length(levels) != length(labels)) { + stop("Error: The length of 'levels' and 'labels' must be the same.") + } + + # Convert the selected columns into a long format + tryCatch({ + table <- dat %>% + select(all_of(questions)) %>% + gather(key = "Question", value = "Answer") %>% + mutate(Answer = factor(Answer, levels = levels, labels = labels)) %>% + group_by(Question, Answer) %>% + summarize(Number = n()) + + return(table) + }, error = function(e) { + stop("Error in processing data: ", e$message) + }) +} diff --git a/R/tools.R b/R/tools.R index a73c942..155cff5 100644 --- a/R/tools.R +++ b/R/tools.R @@ -83,3 +83,31 @@ load_libraries <- function(libraries) { } } } + +#' Group By and Summarise +#' +#' @param dat +#' @param col +#' @param convert_to_percent +#' +#' @return +#' @export +#' +#' @examples +group_by_summarise <- function(dat, col, convert_to_percent = FALSE){ + col_sym <- sym(col) #convert column name to symbol + table <- dat %>% + group_by(!!col_sym) %>% # unquote the symbol + summarise(count = n()) %>% + arrange(desc(count)) + + # Optionally convert count to percent + if (convert_to_percent) { + total_count <- sum(table$count) + table <- table %>% + mutate(percent = count / total_count * 100) + } + + return(table) + +} diff --git a/man/clean_select_all_responses.Rd b/man/clean_select_all_responses.Rd new file mode 100644 index 0000000..7564bb7 --- /dev/null +++ b/man/clean_select_all_responses.Rd @@ -0,0 +1,14 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/tools.R +\name{clean_select_all_responses} +\alias{clean_select_all_responses} +\title{Clean Select All Survey Response Data} +\usage{ +clean_select_all_responses(dat, col) +} +\arguments{ +\item{col}{} +} +\description{ +Clean Select All Survey Response Data +} diff --git a/man/gather_and_summarise.Rd b/man/gather_and_summarise.Rd new file mode 100644 index 0000000..8652278 --- /dev/null +++ b/man/gather_and_summarise.Rd @@ -0,0 +1,14 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/surveys.R +\name{gather_and_summarise} +\alias{gather_and_summarise} +\title{Gather Questions into One Table to Graph Together} +\usage{ +gather_and_summarise(dat, questions, levels, labels) +} +\arguments{ +\item{labels}{} +} +\description{ +Gather Questions into One Table to Graph Together +} diff --git a/man/group_by_summarise.Rd b/man/group_by_summarise.Rd new file mode 100644 index 0000000..f8d0df3 --- /dev/null +++ b/man/group_by_summarise.Rd @@ -0,0 +1,14 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/tools.R +\name{group_by_summarise} +\alias{group_by_summarise} +\title{Group By and Summarise} +\usage{ +group_by_summarise(dat, col, convert_to_percent = FALSE) +} +\arguments{ +\item{convert_to_percent}{} +} +\description{ +Group By and Summarise +} diff --git a/man/map_scheduling_group.Rd b/man/map_scheduling_group.Rd new file mode 100644 index 0000000..78dee48 --- /dev/null +++ b/man/map_scheduling_group.Rd @@ -0,0 +1,27 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/instructor_training.R +\name{map_scheduling_group} +\alias{map_scheduling_group} +\title{Create Scheduling Groups} +\usage{ +map_scheduling_group(df) +} +\arguments{ +\item{df}{Dataframe; The data frame containing timezone information. Comes from Trainer Quarterly Availability Form.} +} +\value{ +Dataframe; The data frame with an additional 'sched_group' +column. +Throws an error if no matching column or multiple matching columns are found. +} +\description{ +Create Scheduling Groups +} +\examples{ +\dontrun{ + # Assume 'data_with_timezones' is a data frame with an appropriate timezone column + grouped_timezones <- map_timezones(data_with_timezones) + print(grouped_timezones) +} + +} From 91b19143069216edc3222e7e55241e6f7dc24c2b Mon Sep 17 00:00:00 2001 From: Kelly Barnes Date: Thu, 23 Nov 2023 10:49:57 -0500 Subject: [PATCH 6/7] documents and fixes tests --- DESCRIPTION | 9 ++- NAMESPACE | 9 ++- R/instructor_training.R | 6 +- R/plotting.R | 80 +++++++++++++++++------ R/surveys.R | 46 +++++++++---- R/tools.R | 64 +++++++++++++----- man/add_text_geom.Rd | 28 ++++++-- man/calculate_nps.Rd | 21 +++++- man/clean_select_all_responses.Rd | 19 +++++- man/custom_scale_x_discrete.Rd | 29 +++++++- man/extract_year_quarter.Rd | 2 +- man/gather_and_summarise.Rd | 26 +++++++- man/group_by_summarise.Rd | 22 ++++++- man/load_libraries.Rd | 14 +++- man/percent_label.Rd | 17 ++++- tests/testthat/test-instructor_training.R | 22 ++++--- 16 files changed, 318 insertions(+), 96 deletions(-) diff --git a/DESCRIPTION b/DESCRIPTION index 08d4771..ccfcc03 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -8,16 +8,15 @@ Description: What the package does (one paragraph). License: MIT + file LICENSE Imports: dplyr, - googlesheets4, stringr, ggplot2, airtabler, - paintbrush, lubridate, - rlang + rlang, + scales, + tidyr Remotes: - bergant/airtabler, - klbarnes20/paintbrush + bergant/airtabler Encoding: UTF-8 Roxygen: list(markdown = TRUE) RoxygenNote: 7.2.3 diff --git a/NAMESPACE b/NAMESPACE index 42b163f..172186d 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -36,9 +36,13 @@ export(trainees_n_days) import(dplyr) importFrom(airtabler,airtable) importFrom(dplyr,case_when) +importFrom(dplyr,count) importFrom(dplyr,filter) +importFrom(dplyr,group_by) importFrom(dplyr,mutate) importFrom(dplyr,rename) +importFrom(dplyr,select) +importFrom(dplyr,summarize) importFrom(ggplot2,aes_string) importFrom(ggplot2,facet_grid) importFrom(ggplot2,geom_col) @@ -46,7 +50,10 @@ importFrom(ggplot2,geom_text) importFrom(ggplot2,ggplot) importFrom(ggplot2,ggsave) importFrom(lubridate,year) -importFrom(paintbrush,theme_carpentries) importFrom(rlang,sym) +importFrom(scales,label_percent) importFrom(stringr,str_detect) +importFrom(stringr,str_trim) +importFrom(tidyr,gather) +importFrom(tidyr,separate_rows) importFrom(utils,read.csv) diff --git a/R/instructor_training.R b/R/instructor_training.R index 761ebf4..ce6c75e 100644 --- a/R/instructor_training.R +++ b/R/instructor_training.R @@ -119,7 +119,7 @@ map_timezones <- function(df) { stringr::str_detect(timezone, "\\bUTC[-]2[:]?30\\b") ~ "TZ3", stringr::str_detect(timezone, "\\bUTC[-]3\\b") ~ "TZ3", stringr::str_detect(timezone, "\\bUTC[-]1\\b") ~ "TZ3", - stringr::str_detect(timezone, "\\bUTC[ ]?0\\b") ~ "TZ4", + stringr::str_detect(timezone, "\\bUTC[)]\\b") ~ "TZ4", stringr::str_detect(timezone, "\\bUTC[+]1\\b") ~ "TZ4", stringr::str_detect(timezone, "\\bUTC[+]2\\b") ~ "TZ4", stringr::str_detect(timezone, "\\bUTC[+]3\\b") ~ "TZ4", @@ -184,7 +184,7 @@ map_scheduling_group <- function(df) { FD_PT = ifelse( str_detect(timezone, "UTC[-]10|UTC[-]9|UTC[-]8|UTC[-]7|UTC[-]6"), "FD_PT", NA), # PST +/- 2 FD_CET = ifelse( - str_detect(timezone, "UTC[-]1|UTC[ ]?0|UTC[+]1|UTC[+]2"), "FD_CET", NA), # CEST +/- 2 + str_detect(timezone, "UTC[-]1|UTC[)]|UTC[+]1|UTC[+]2"), "FD_CET", NA), # CEST +/- 2 FD_AET = ifelse( str_detect(timezone, "UTC[+]12|UTC[+]11|UTC[+]10|UTC[+]9|UTC[+]8"), "FD_AET", NA), # AEST +/- 2 HD_PM_PT = ifelse( @@ -204,7 +204,7 @@ map_scheduling_group <- function(df) { #' Extract Quarter and Year Information from Data Frame Name #' #' This function extracts the quarter and year information from a given data frame name. -#' The name is expected to be in the format "Q[1-4]_[YYYY]" where [1-4] is the quarter and [YYYY] is the year. +#' The name is expected to be in the format "Q(1-4)_(YYYY)" where (1-4) is the quarter and (YYYY) is the year. #' #' @param filename Dataframe; The data frame whose name you want to analyze. #' diff --git a/R/plotting.R b/R/plotting.R index 7b6dd1c..70e1187 100644 --- a/R/plotting.R +++ b/R/plotting.R @@ -13,7 +13,6 @@ #' @return A ggplot object representing the generated plot. #' @export #' @importFrom ggplot2 ggplot aes_string geom_col geom_text facet_grid -#' @importFrom paintbrush theme_carpentries # #' #' @examples @@ -27,8 +26,7 @@ generate_plot <- function(dat, x, y, fill = NULL) { plot <- ggplot(dat, aes_string(x = x, y = y, fill = fill)) + geom_col(position = position_dodge(width = 0.9)) + geom_text(aes(label = after_stat(y)), stat = "identity", vjust = -0.3, position = position_dodge(width = 0.9)) + - facet_grid(year ~ quarter) + - theme_carpentries() + facet_grid(year ~ quarter) return(plot) } @@ -58,35 +56,67 @@ save_plot <- function(dir, plot) { ggsave(path, plot = plot, device = 'png', dpi = 300, width = 4, height = 3) } -#' Add Data Labels to Plot -#' -#' @param label_type -#' @param accuracy -#' @param color -#' @param vjust -#' @param fontface -#' -#' @return +#' Add Data Labels to a ggplot2 Plot +#' +#' This function adds text labels to a ggplot2 plot. It supports two types of labels: counts and percentages. +#' The labels can be customized in terms of their accuracy, color, vertical adjustment, and font face. +#' +#' @param label_type A character string specifying the type of label to add. +#' Acceptable values are "count" for count labels and "percent" for percentage labels. +#' @param accuracy An optional numeric value specifying the number of decimal places for percentage labels. +#' Only applicable if `label_type` is "percent". Default is 0.1. +#' @param color A character string specifying the color of the text labels. Default is "white". +#' @param vjust A numeric value for vertical adjustment of the text labels. +#' Positive values move text up, and negative values move it down. Default is 1.6. +#' @param fontface A character string specifying the font face for text labels. +#' Common values are "plain", "bold", "italic", "bold.italic". Default is "bold". +#' @param nudge_x A numeric value specifying horizontal adjustment of the text labels. +#' Positive values move text to the right, and negative values move it to the left. Default is 0. +#' +#' @importFrom ggplot2 geom_text +#' @importFrom scales label_percent +#' +#' @return A ggplot2 layer with the specified text labels added. #' @export #' #' @examples -add_text_geom <- function(label_type = "count", accuracy = 0.1, color = "white", vjust = 1.6, fontface = "bold") { + + +add_text_geom <- function(label_type = "count", accuracy = 0.1, color = "white", vjust = 1.6, fontface = "bold", nudge_x = 0) { if (label_type == "count") { - plot + geom_text(aes(label = count), color = color, vjust = vjust, fontface = fontface) + plot + geom_text(aes(label = count), color = color, vjust = vjust, nudge_x = nudge_x, fontface = fontface) } else if (label_type == "percent") { geom_text(aes(label = scales::label_percent(accuracy = accuracy)(percent)), color = color, vjust = vjust, fontface = fontface) } } -#' Format and Text Wrap X Axis Labels +#' Format and Text Wrap X Axis Labels in ggplot2 +#' +#' This function applies text wrapping to x-axis labels in a ggplot2 plot. +#' It allows for customizing the width of the wrap, making long labels more readable by breaking them into multiple lines. #' -#' @param labels -#' @param wrap_width +#' @param labels A vector of labels to be used for the x-axis. +#' These labels should correspond to the categories or values present on the x-axis. +#' @param wrap_width An integer specifying the maximum width (in characters) before wrapping a label onto the next line. +#' The default value is 15. #' -#' @return +#' @return A ggplot2 scale layer, specifically a modified `scale_x_discrete`, +#' with the labels formatted to wrap text based on the specified `wrap_width`. #' @export #' #' @examples +#' # Example using the diamonds dataset from ggplot2 +#' library(ggplot2) +#' data(diamonds) +#' +#' # Create artificial long labels for illustration +#' long_labels <- c("Fair Quality Cut", "Good Quality Cut", "Very Good Quality Cut", +#' "Premium Quality Cut", "Ideal Quality Cut") +#' names(long_labels) <- levels(diamonds$cut) +#' +#' basic_plot <- ggplot(diamonds, aes(x = cut, y = price)) + geom_bar(stat = "identity") +#' # Apply custom scale with wrapped labels +#' basic_plot + custom_scale_x_discrete(labels = long_labels, wrap_width = 10) custom_scale_x_discrete <- function(labels, wrap_width = 15) { scale_x_discrete( drop = FALSE, @@ -100,13 +130,21 @@ custom_scale_x_discrete <- function(labels, wrap_width = 15) { #' Add Percent Sign to Data Label #' -#' @param x -#' @param decimal +#' This function formats numeric values as percentages. It rounds the numbers to the specified decimal places and appends a percent sign. +#' +#' @param x Numeric vector; the values to be formatted as percentages. +#' @param decimal Integer; the number of decimal places to round the numeric values. +#' Defaults to 1, indicating one decimal place. #' -#' @return +#' @return A character vector with the numeric values formatted as percentages. #' @export #' #' @examples +#' # Example usage of percent_label +#' numeric_values <- c(0.123, 0.456, 0.789) +#' percent_labels <- percent_label(numeric_values) +#' print(percent_labels) +#' # Output: "12.3%", "45.6%", "78.9%" percent_label <- function(x, decimal = 1) { paste0(round(x, decimal), "%") } diff --git a/R/surveys.R b/R/surveys.R index 81e1521..90a2c0b 100644 --- a/R/surveys.R +++ b/R/surveys.R @@ -1,18 +1,24 @@ -#' Calculate Net Promoter Score +#' Calculate Net Promoter Score (NPS) #' -#' #'How to calculate net promoter score: https://monkeylear.com/blog/nps-analysis/ +#' This function calculates the Net Promoter Score from survey data based on respondents' ratings. +#' NPS is a measure of customer loyalty and is calculated using the formula: +#' Percentage of Promoters - Percentage of Detractors. +#' For more information on NPS, visit: https://monkeylearn.com/blog/nps-analysis/ #' -#' @param dat -#' @param col +#' @param dat A data frame containing survey data. +#' @param col A character string specifying the name of the column containing NPS ratings (expected to be numeric). #' -#' @return +#' @return A data frame summarizing the number and percentage of respondents in each category: +#' Promoters, Passives, and Detractors. #' @export -#' - #' #' @examples +#' # Example usage with a sample data frame +#' sample_data <- data.frame(rating = sample(0:10, 100, replace = TRUE)) +#' nps_result <- calculate_nps(sample_data, "rating") +#' print(nps_result) calculate_nps <- function(dat, col) { # Ensure col is a character vector of length 1 if (!is.character(col) || length(col) != 1) { @@ -43,17 +49,31 @@ calculate_nps <- function(dat, col) { } -#' Gather Questions into One Table to Graph Together +#' Gather Questions into One Table for Graphing +#' +#' This function transforms survey data by converting selected question columns into a long format +#' suitable for comparison and graphing. It facilitates analysis across multiple questions. +#' +#' @param dat A data frame containing survey data. +#' @param questions A character vector of column names in 'dat' representing the questions to be summarized. +#' @param levels A vector of the levels (possible responses) for the questions. +#' @param labels A vector of labels corresponding to the 'levels' vector for re-labeling responses. #' -#' @param dat -#' @param questions -#' @param levels -#' @param labels +#' @importFrom dplyr select mutate group_by summarize +#' @importFrom tidyr gather #' -#' @return +#' @return A data frame in long format, with each row representing a response to a question, +#' along with the count of each response type. #' @export #' #' @examples +#' # Example usage with a sample data frame +#' sample_data <- data.frame(Q1 = sample(1:5, 100, replace = TRUE), Q2 = sample(1:5, 100, replace = TRUE)) +#' questions <- c("Q1", "Q2") +#' levels <- 1:5 +#' labels <- c("Strongly Disagree", "Disagree", "Neutral", "Agree", "Strongly Agree") +#' summarised_data <- gather_and_summarise(sample_data, questions, levels, labels) +#' print(summarised_data) gather_and_summarise <- function(dat, questions, levels, labels){ # Validation Checks if (!is.data.frame(dat)) { diff --git a/R/tools.R b/R/tools.R index 155cff5..b62a145 100644 --- a/R/tools.R +++ b/R/tools.R @@ -49,32 +49,49 @@ set_time_frame <- function(dat, col, start, end) { return(df) } -#' Clean Select All Survey Response Data +#' Clean and Summarize "Select All That Apply" Survey Responses #' -#' @param dat -#' @param col +#' This function processes survey data where respondents could select multiple answers (e.g., "Select all that apply" questions). +#' It separates the responses, trims whitespace, and counts the occurrences of each unique response. #' -#' @return +#' @param dat A data frame containing the survey data. +#' @param col A character string specifying the name of the column with the "select all" responses. +#' +#' @importFrom dplyr mutate count +#' @importFrom tidyr separate_rows +#' @importFrom stringr str_trim +#' +#' @return A data frame with each row representing a unique response from the specified column +#' and its count in the survey. #' @export #' #' @examples +#' # Example usage with a sample data frame +#' sample_data <- data.frame(responses = c("Option 1, Option 2", "Option 2, Option 3", "Option 1, Option 3, Option 2","Option 2","Option 3")) +#' cleaned_responses <- clean_select_all_responses(sample_data, "responses") +#' print(cleaned_responses) clean_select_all_responses <- function(dat, col) { col_sym <- sym(col) - response_table <- data %>% - separate_rows(col_sym, sep = ",") %>% - mutate(col = str_trim(col)) %>% - count(col) + response_table <- dat %>% + separate_rows(!!col_sym, sep = ",") %>% + mutate(!!col_sym := str_trim(!!col_sym)) %>% + count(!!col_sym) return(response_table) } -#' Load Libraries +#' Load a List of R Libraries, Installing if Necessary +#' +#' This function iterates through a list of R package names, checks if they are installed, +#' and loads them into the R session. It installs any package that is not already installed. #' -#' @param libraries +#' @param libraries A character vector of R package names to be loaded. #' -#' @return +#' @return None; the function is called for its side effects (loading libraries). #' @export #' #' @examples +#' # Example usage to load dplyr and ggplot2 +#' load_libraries(c("dplyr", "ggplot2")) load_libraries <- function(libraries) { for (lib in libraries) { if (!require(lib, character.only = TRUE)) { @@ -84,28 +101,39 @@ load_libraries <- function(libraries) { } } -#' Group By and Summarise +#' Group Data by a Specified Column and Summarize Counts #' -#' @param dat -#' @param col -#' @param convert_to_percent +#' This function groups a data frame by the values in a specified column, then calculates +#' the count of records in each group. Optionally, it can convert these counts into percentages. #' -#' @return +#' @param dat A data frame to be analyzed. +#' @param col A character string specifying the column name by which to group the data. +#' @param convert_to_percent A logical value; if TRUE, convert counts to percentages. +#' Default is FALSE. +#' +#' @return A data frame with each group (from the specified column) and its count (and optionally, percentage). #' @export #' #' @examples +#' # Example usage with a sample data frame +#' set.seed(1) # for reproducibility +#' sample_data <- data.frame(category = sample(c("A", "B", "C"), 120, replace = TRUE, prob = c(0.3, 0.5, 0.2))) + +#' summary_table <- group_by_summarise(sample_data, "category", convert_to_percent = TRUE) +#' print(summary_table) group_by_summarise <- function(dat, col, convert_to_percent = FALSE){ col_sym <- sym(col) #convert column name to symbol table <- dat %>% group_by(!!col_sym) %>% # unquote the symbol - summarise(count = n()) %>% + summarise(count = n(), .groups = 'drop') %>% arrange(desc(count)) # Optionally convert count to percent if (convert_to_percent) { total_count <- sum(table$count) + table <- table %>% - mutate(percent = count / total_count * 100) + mutate(percent = (count / total_count) * 100) } return(table) diff --git a/man/add_text_geom.Rd b/man/add_text_geom.Rd index d614256..ad23076 100644 --- a/man/add_text_geom.Rd +++ b/man/add_text_geom.Rd @@ -2,19 +2,39 @@ % Please edit documentation in R/plotting.R \name{add_text_geom} \alias{add_text_geom} -\title{Add Data Labels to Plot} +\title{Add Data Labels to a ggplot2 Plot} \usage{ add_text_geom( label_type = "count", accuracy = 0.1, color = "white", vjust = 1.6, - fontface = "bold" + fontface = "bold", + nudge_x = 0 ) } \arguments{ -\item{fontface}{} +\item{label_type}{A character string specifying the type of label to add. +Acceptable values are "count" for count labels and "percent" for percentage labels.} + +\item{accuracy}{An optional numeric value specifying the number of decimal places for percentage labels. +Only applicable if \code{label_type} is "percent". Default is 0.1.} + +\item{color}{A character string specifying the color of the text labels. Default is "white".} + +\item{vjust}{A numeric value for vertical adjustment of the text labels. +Positive values move text up, and negative values move it down. Default is 1.6.} + +\item{fontface}{A character string specifying the font face for text labels. +Common values are "plain", "bold", "italic", "bold.italic". Default is "bold".} + +\item{nudge_x}{A numeric value specifying horizontal adjustment of the text labels. +Positive values move text to the right, and negative values move it to the left. Default is 0.} +} +\value{ +A ggplot2 layer with the specified text labels added. } \description{ -Add Data Labels to Plot +This function adds text labels to a ggplot2 plot. It supports two types of labels: counts and percentages. +The labels can be customized in terms of their accuracy, color, vertical adjustment, and font face. } diff --git a/man/calculate_nps.Rd b/man/calculate_nps.Rd index 30fcb9b..17eaf2f 100644 --- a/man/calculate_nps.Rd +++ b/man/calculate_nps.Rd @@ -2,13 +2,28 @@ % Please edit documentation in R/surveys.R \name{calculate_nps} \alias{calculate_nps} -\title{Calculate Net Promoter Score} +\title{Calculate Net Promoter Score (NPS)} \usage{ calculate_nps(dat, col) } \arguments{ -\item{col}{} +\item{dat}{A data frame containing survey data.} + +\item{col}{A character string specifying the name of the column containing NPS ratings (expected to be numeric).} +} +\value{ +A data frame summarizing the number and percentage of respondents in each category: +Promoters, Passives, and Detractors. } \description{ -#'How to calculate net promoter score: https://monkeylear.com/blog/nps-analysis/ +This function calculates the Net Promoter Score from survey data based on respondents' ratings. +NPS is a measure of customer loyalty and is calculated using the formula: +Percentage of Promoters - Percentage of Detractors. +For more information on NPS, visit: https://monkeylearn.com/blog/nps-analysis/ +} +\examples{ +# Example usage with a sample data frame +sample_data <- data.frame(rating = sample(0:10, 100, replace = TRUE)) +nps_result <- calculate_nps(sample_data, "rating") +print(nps_result) } diff --git a/man/clean_select_all_responses.Rd b/man/clean_select_all_responses.Rd index 7564bb7..e695fd3 100644 --- a/man/clean_select_all_responses.Rd +++ b/man/clean_select_all_responses.Rd @@ -2,13 +2,26 @@ % Please edit documentation in R/tools.R \name{clean_select_all_responses} \alias{clean_select_all_responses} -\title{Clean Select All Survey Response Data} +\title{Clean and Summarize "Select All That Apply" Survey Responses} \usage{ clean_select_all_responses(dat, col) } \arguments{ -\item{col}{} +\item{dat}{A data frame containing the survey data.} + +\item{col}{A character string specifying the name of the column with the "select all" responses.} +} +\value{ +A data frame with each row representing a unique response from the specified column +and its count in the survey. } \description{ -Clean Select All Survey Response Data +This function processes survey data where respondents could select multiple answers (e.g., "Select all that apply" questions). +It separates the responses, trims whitespace, and counts the occurrences of each unique response. +} +\examples{ +# Example usage with a sample data frame +sample_data <- data.frame(responses = c("Option 1, Option 2", "Option 2, Option 3", "Option 1, Option 3, Option 2","Option 2","Option 3")) +cleaned_responses <- clean_select_all_responses(sample_data, "responses") +print(cleaned_responses) } diff --git a/man/custom_scale_x_discrete.Rd b/man/custom_scale_x_discrete.Rd index 148451f..342280e 100644 --- a/man/custom_scale_x_discrete.Rd +++ b/man/custom_scale_x_discrete.Rd @@ -2,13 +2,36 @@ % Please edit documentation in R/plotting.R \name{custom_scale_x_discrete} \alias{custom_scale_x_discrete} -\title{Format and Text Wrap X Axis Labels} +\title{Format and Text Wrap X Axis Labels in ggplot2} \usage{ custom_scale_x_discrete(labels, wrap_width = 15) } \arguments{ -\item{wrap_width}{} +\item{labels}{A vector of labels to be used for the x-axis. +These labels should correspond to the categories or values present on the x-axis.} + +\item{wrap_width}{An integer specifying the maximum width (in characters) before wrapping a label onto the next line. +The default value is 15.} +} +\value{ +A ggplot2 scale layer, specifically a modified \code{scale_x_discrete}, +with the labels formatted to wrap text based on the specified \code{wrap_width}. } \description{ -Format and Text Wrap X Axis Labels +This function applies text wrapping to x-axis labels in a ggplot2 plot. +It allows for customizing the width of the wrap, making long labels more readable by breaking them into multiple lines. +} +\examples{ +# Example using the diamonds dataset from ggplot2 +library(ggplot2) +data(diamonds) + +# Create artificial long labels for illustration +long_labels <- c("Fair Quality Cut", "Good Quality Cut", "Very Good Quality Cut", + "Premium Quality Cut", "Ideal Quality Cut") +names(long_labels) <- levels(diamonds$cut) + +basic_plot <- ggplot(diamonds, aes(x = cut, y = price)) + geom_bar(stat = "identity") +# Apply custom scale with wrapped labels +basic_plot + custom_scale_x_discrete(labels = long_labels, wrap_width = 10) } diff --git a/man/extract_year_quarter.Rd b/man/extract_year_quarter.Rd index 9ed8fa4..1b6337f 100644 --- a/man/extract_year_quarter.Rd +++ b/man/extract_year_quarter.Rd @@ -15,7 +15,7 @@ The function will throw an error if the name does not match the expected format. } \description{ This function extracts the quarter and year information from a given data frame name. -The name is expected to be in the format "Q\link{1-4}_\link{YYYY}" where \link{1-4} is the quarter and \link{YYYY} is the year. +The name is expected to be in the format "Q(1-4)_(YYYY)" where (1-4) is the quarter and (YYYY) is the year. } \examples{ \dontrun{ diff --git a/man/gather_and_summarise.Rd b/man/gather_and_summarise.Rd index 8652278..cd462a5 100644 --- a/man/gather_and_summarise.Rd +++ b/man/gather_and_summarise.Rd @@ -2,13 +2,33 @@ % Please edit documentation in R/surveys.R \name{gather_and_summarise} \alias{gather_and_summarise} -\title{Gather Questions into One Table to Graph Together} +\title{Gather Questions into One Table for Graphing} \usage{ gather_and_summarise(dat, questions, levels, labels) } \arguments{ -\item{labels}{} +\item{dat}{A data frame containing survey data.} + +\item{questions}{A character vector of column names in 'dat' representing the questions to be summarized.} + +\item{levels}{A vector of the levels (possible responses) for the questions.} + +\item{labels}{A vector of labels corresponding to the 'levels' vector for re-labeling responses.} +} +\value{ +A data frame in long format, with each row representing a response to a question, +along with the count of each response type. } \description{ -Gather Questions into One Table to Graph Together +This function transforms survey data by converting selected question columns into a long format +suitable for comparison and graphing. It facilitates analysis across multiple questions. +} +\examples{ +# Example usage with a sample data frame +sample_data <- data.frame(Q1 = sample(1:5, 100, replace = TRUE), Q2 = sample(1:5, 100, replace = TRUE)) +questions <- c("Q1", "Q2") +levels <- 1:5 +labels <- c("Strongly Disagree", "Disagree", "Neutral", "Agree", "Strongly Agree") +summarised_data <- gather_and_summarise(sample_data, questions, levels, labels) +print(summarised_data) } diff --git a/man/group_by_summarise.Rd b/man/group_by_summarise.Rd index f8d0df3..d25ee70 100644 --- a/man/group_by_summarise.Rd +++ b/man/group_by_summarise.Rd @@ -2,13 +2,29 @@ % Please edit documentation in R/tools.R \name{group_by_summarise} \alias{group_by_summarise} -\title{Group By and Summarise} +\title{Group Data by a Specified Column and Summarize Counts} \usage{ group_by_summarise(dat, col, convert_to_percent = FALSE) } \arguments{ -\item{convert_to_percent}{} +\item{dat}{A data frame to be analyzed.} + +\item{col}{A character string specifying the column name by which to group the data.} + +\item{convert_to_percent}{A logical value; if TRUE, convert counts to percentages. +Default is FALSE.} +} +\value{ +A data frame with each group (from the specified column) and its count (and optionally, percentage). } \description{ -Group By and Summarise +This function groups a data frame by the values in a specified column, then calculates +the count of records in each group. Optionally, it can convert these counts into percentages. +} +\examples{ +# Example usage with a sample data frame +set.seed(1) # for reproducibility +sample_data <- data.frame(category = sample(c("A", "B", "C"), 120, replace = TRUE, prob = c(0.3, 0.5, 0.2))) +summary_table <- group_by_summarise(sample_data, "category", convert_to_percent = TRUE) +print(summary_table) } diff --git a/man/load_libraries.Rd b/man/load_libraries.Rd index f6002c4..191b0e7 100644 --- a/man/load_libraries.Rd +++ b/man/load_libraries.Rd @@ -2,13 +2,21 @@ % Please edit documentation in R/tools.R \name{load_libraries} \alias{load_libraries} -\title{Load Libraries} +\title{Load a List of R Libraries, Installing if Necessary} \usage{ load_libraries(libraries) } \arguments{ -\item{libraries}{} +\item{libraries}{A character vector of R package names to be loaded.} +} +\value{ +None; the function is called for its side effects (loading libraries). } \description{ -Load Libraries +This function iterates through a list of R package names, checks if they are installed, +and loads them into the R session. It installs any package that is not already installed. +} +\examples{ +# Example usage to load dplyr and ggplot2 +load_libraries(c("dplyr", "ggplot2")) } diff --git a/man/percent_label.Rd b/man/percent_label.Rd index 613441e..d50710c 100644 --- a/man/percent_label.Rd +++ b/man/percent_label.Rd @@ -7,8 +7,21 @@ percent_label(x, decimal = 1) } \arguments{ -\item{decimal}{} +\item{x}{Numeric vector; the values to be formatted as percentages.} + +\item{decimal}{Integer; the number of decimal places to round the numeric values. +Defaults to 1, indicating one decimal place.} +} +\value{ +A character vector with the numeric values formatted as percentages. } \description{ -Add Percent Sign to Data Label +This function formats numeric values as percentages. It rounds the numbers to the specified decimal places and appends a percent sign. +} +\examples{ +# Example usage of percent_label +numeric_values <- c(0.123, 0.456, 0.789) +percent_labels <- percent_label(numeric_values) +print(percent_labels) +# Output: "12.3\%", "45.6\%", "78.9\%" } diff --git a/tests/testthat/test-instructor_training.R b/tests/testthat/test-instructor_training.R index f12d868..d0ed048 100644 --- a/tests/testthat/test-instructor_training.R +++ b/tests/testthat/test-instructor_training.R @@ -3,7 +3,8 @@ test_that("map_availability works with expected input and renames the column", { df <- data.frame( "Are you available to teach" = c("Yes, I am available to teach online Instructor Training", "No, I can NOT teach online events next quarter.", - "Maybe, but I am not able to schedule firmly at this time.") + "Maybe, but I am not able to schedule firmly at this time."), + check.names = FALSE ) result <- map_availability(df) expect_equal(result$availability, c("yes", "no", "maybe")) @@ -19,15 +20,15 @@ test_that("map_availability throws error if no matching column exists", { # Test if map_availability fails if multiple matching columns test_that("map_availability fails if multiple matching columns", { df <- data.frame( - "Are.you.available.to.teach" = c("Yes", "No"), - "Are.you.available.to.teach.online" = c("Yes", "No") + "Are you available to teach" = c("Yes", "No"), + "Are you available to teach.online" = c("Yes", "No"), check.names = FALSE ) expect_error(map_availability(df), "Error: Multiple matching columns found.") }) # Test if map_availability leaves other columns unchanged test_that("map_availability leaves other columns unchanged", { - df <- data.frame("Name" = c("Alice", "Bob"), "Are you available to teach" = c("Yes", "No")) + df <- data.frame("Name" = c("Alice", "Bob"), "Are you available to teach" = c("Yes", "No"), check.names = FALSE) df_out <- map_availability(df) expect_true("Name" %in% names(df_out)) }) @@ -35,7 +36,7 @@ test_that("map_availability leaves other columns unchanged", { # Test if map_availability maps unknown values unchanged test_that("map_availability maps unknown values unchanged", { df <- data.frame( - "Are you available to teach" = c("Unknown value") + "Are you available to teach" = c("Unknown value"), check.names = FALSE ) result <- map_availability(df) expect_equal(result$availability, "Unknown value") @@ -44,7 +45,7 @@ test_that("map_availability maps unknown values unchanged", { test_that("map_timezones works with expected input", { df <- data.frame( - "What time zone are you located in?" = c("UTC+1", "UTC-5", "UTC+10") + "What time zone are you located in?" = c("UTC+1", "UTC-5", "UTC+10"), check.names = FALSE ) result <- map_timezones(df) expect_equal(result$TZgroup, c("TZ4", "TZ2", "TZ6")) @@ -52,7 +53,8 @@ test_that("map_timezones works with expected input", { test_that("map_timezones renames the timezone column", { df <- data.frame( - "What time zone are you located in?" = c("UTC+1") + "What time zone are you located in?" = c("UTC+1"), + check.names = FALSE ) result <- map_timezones(df) expect_true("timezone" %in% names(result)) @@ -60,7 +62,7 @@ test_that("map_timezones renames the timezone column", { test_that("map_timezones handles unknown timezones", { df <- data.frame( - "What time zone are you located in?" = c("Mars Standard Time") + "What time zone are you located in?" = c("Mars Standard Time"), check.names = FALSE ) result <- map_timezones(df) expect_equal(result$TZgroup, "TZother") @@ -101,7 +103,7 @@ test_that("summarise_data_by_qtr works as expected", { # Step 1: Mock data frame mock_data <- data.frame( "What time zone are you located in?" = c("UTC+1", "UTC-5", "UTC+10"), - "Are you available to teach" = c("yes", "no", "maybe") + "Are you available to teach" = c("yes", "no", "maybe"), check.names = FALSE ) # Step 2: Expected result @@ -129,7 +131,7 @@ test_that("summarise_data_by_tz works as expected", { # Mock data frame mock_data <- data.frame( "What time zone are you located in?" = c("UTC+1", "UTC-5", "UTC+10"), - "Are you available to teach" = c("yes", "no", "maybe") + "Are you available to teach" = c("yes", "no", "maybe"), check.names = FALSE ) # Expected result From 6cc50ba2940b3934c16e9de3f247566281ba7dd1 Mon Sep 17 00:00:00 2001 From: Kelly Barnes Date: Thu, 23 Nov 2023 10:58:18 -0500 Subject: [PATCH 7/7] updates NEWS --- NEWS.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/NEWS.md b/NEWS.md index d1a62b3..8cb2d43 100644 --- a/NEWS.md +++ b/NEWS.md @@ -1,3 +1,3 @@ -2# caliper (development version) +# caliper (development version) * Initial CRAN submission.