Skip to content

Commit

Permalink
Merge pull request #120 from atorus-research/devel
Browse files Browse the repository at this point in the history
1.1.0 Release
  • Loading branch information
mstackhouse committed Jan 10, 2023
2 parents c388147 + 004a8e0 commit b9011de
Show file tree
Hide file tree
Showing 115 changed files with 4,278 additions and 2,728 deletions.
10 changes: 7 additions & 3 deletions DESCRIPTION
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
Package: Tplyr
Title: A Traceability Focused Grammar of Clinical Data Summary
Version: 1.0.2
Version: 1.1.0
Authors@R:
c(
person(given = "Eli",
Expand All @@ -20,8 +20,12 @@ Authors@R:
person(given = "Nathan",
family = "Kosiba",
email = "Nathan.Kosiba@atorusresearch.com",
role = "aut",
role = "ctb",
comment = c(ORCID = "0000-0001-5359-4234")),
person(given = "Sadchla",
family = "Mascary",
email = "sadchla.mascary@atorusresearch.com",
role = "ctb"),
person(given = "Atorus Research LLC",
role = "cph")
)
Expand Down Expand Up @@ -55,6 +59,6 @@ Suggests:
pharmaRTF,
withr
VignetteBuilder: knitr
RoxygenNote: 7.2.1
RoxygenNote: 7.2.3
RdMacros: lifecycle
Config/testthat/edition: 3
5 changes: 5 additions & 0 deletions NAMESPACE
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ export(add_total_row)
export(add_treat_grps)
export(add_variables)
export(append_metadata)
export(apply_conditional_format)
export(apply_formats)
export(apply_row_masks)
export(build)
Expand All @@ -69,6 +70,7 @@ export(get_precision_on)
export(get_shift_layer_formats)
export(get_stats_data)
export(get_target_var)
export(get_tplyr_regex)
export(get_where)
export(group_count)
export(group_desc)
Expand Down Expand Up @@ -114,6 +116,8 @@ export(set_target_var)
export(set_total_row_label)
export(set_treat_var)
export(set_where)
export(str_extract_fmt_group)
export(str_extract_num)
export(str_indent_wrap)
export(tplyr_layer)
export(tplyr_meta)
Expand Down Expand Up @@ -231,6 +235,7 @@ importFrom(stats,median)
importFrom(stats,quantile)
importFrom(stats,sd)
importFrom(stats,var)
importFrom(stringr,"str_sub<-")
importFrom(stringr,fixed)
importFrom(stringr,regex)
importFrom(stringr,str_count)
Expand Down
7 changes: 7 additions & 0 deletions NEWS.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,10 @@
# Tplyr 1.1.0
- This release incorporate parenthesis hugging across all layers (#117)
- New functions `apply_conditional_formats()`, `str_extract_fmt_group()` and `str_extract_num()`
- Vignette reorganization, as well as new vignettes added
- Bug fix for #115
- Scroll bar added to articles menu on pkgdown (Thanks @mattroumaya and @MayaGans!!!)

# Tplyr 1.0.2
- Bug fixes
- Resolve issue with `where` logic when using population data.
Expand Down
131 changes: 131 additions & 0 deletions R/apply_conditional_format.R
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
#' Validator for apply_conditional_format
#'
#' @param string Target character vector where text may be replaced
#' @param format_group An integer representing the targeted numeric field within
#' the string, numbered from left to right
#' @param condition An expression, using the variable name 'x' as the target
#' variable within the condition
#' @param replacement A string to use as the replacement value
#' @param full_string TRUE if the full string should be replaced, FALSE if the
#' replacement should be done within the format group
#' @noRd
validate_conditional_format_params <- function(string, format_group, condition, replacement, full_string) {
if (!inherits(string, "character")) {
stop("Paramter `string` must be a character vector", call.=FALSE)
}

if (!inherits(format_group, "numeric") || (inherits(format_group, "numeric") && format_group %% 1 != 0)) {
stop("Paramter `format_group` must be an integer", call.=FALSE)
}

if (!inherits(replacement, "character")) {
stop("Paramter `replacement` must be a string", call.=FALSE)
}

# Condition statement must use the variable name 'x'
if (!identical(all.vars(condition), "x")) {
stop("Condition must be a valid expression only using the variable name `x`", call.=FALSE)
}

if (!inherits(full_string, "logical")) {
stop("Paramter `full_string` must be bool", call.=FALSE)
}

}

#' Conditional reformatting of a pre-populated string of numbers
#'
#' This function allows you to conditionally re-format a string of numbers based
#' on a numeric value within the string itself. By selecting a "format group",
#' which is targeting a specific number within the string, a user can establish
#' a condition upon which a provided replacement string can be used. Either the
#' entire replacement can be used to replace the entire string, or the
#' replacement text can refill the "format group" while preserving the original
#' width and alignment of the target string.
#'
#' @param string Target character vector where text may be replaced
#' @param format_group An integer representing the targeted numeric field within
#' the string, numbered from left to right
#' @param condition An expression, using the variable name 'x' as the target
#' variable within the condition
#' @param replacement A string to use as the replacement value
#' @param full_string TRUE if the full string should be replaced, FALSE if the
#' replacement should be done within the format group
#'
#' @return A character vector
#' @export
#'
#' @examples
#'
#' string <- c(" 0 (0.0%)", " 8 (9.3%)", "78 (90.7%)")
#'
#' apply_conditional_format(string, 2, x == 0, " 0 ", full_string=TRUE)
#'
#' apply_conditional_format(string, 2, x < 1, "(<1%)")
#'
apply_conditional_format <- function(string, format_group, condition, replacement, full_string=FALSE) {

condition <- enexpr(condition)

# Validate all parameters
validate_conditional_format_params(string, format_group, condition, replacement, full_string)

# Pull out regex to drive the work
f_grp_rx <- get_format_group_regex()

# Pull out all the match groups and then get the numeric for the conditional number
match_groups <- str_match_all(string, f_grp_rx)

# Get the number upon which the condition will be evaluated
x <- map_dbl(
match_groups,
~ if (nrow(.) < format_group) {NA_real_} else {as.double(.[format_group, 2])}
)

# Get the bool vector for where strings should be replaced and handle NAs
tf <- replace_na(eval(condition), FALSE)

if (full_string) {
out_string <- if_else(tf, replacement, string)
} else {
# Grab the match locations to use for sub stringing
match_locs <- str_locate_all(string, f_grp_rx)
# Get the group length out to ensure that the string is fully padded
group_length <- map_int(
match_groups,
~ if (nrow(.) < format_group) {NA_integer_} else {as.integer(nchar(.[format_group, 1]))}
)

if (any(nchar(replacement) > group_length[!is.na(group_length)])) {
warning(
paste0("Replacement string length is longer that some string's format group length.",
"Some alignment will not be preserved")
)
}

# Pad at least as long as the format group space
pad_length <- map_int(
group_length,
~ if_else(nchar(replacement) > ., nchar(replacement), .)
)

# Pull out locs for the format group
end_locs <- map_int(
match_locs,
~ if (nrow(.) < format_group) {NA_integer_} else {.[format_group, 'end']}
)
start_locs <- end_locs - pad_length + 1

# Build the sub string matrix
sub_mat <- matrix(c(rbind(start_locs, end_locs)), ncol=2, byrow=TRUE)

# Generate a vector with replacements already done
rep_string <- string
str_sub(rep_string, sub_mat) <- str_pad(replacement, pad_length)

out_string <- if_else(tf, rep_string, string)
}

out_string
}

7 changes: 5 additions & 2 deletions R/count.R
Original file line number Diff line number Diff line change
Expand Up @@ -342,10 +342,13 @@ prepare_format_metadata.count_layer <- function(x) {

# If a layer_width flag is present, edit the formatting string to display the maximum
# character length
if (str_detect(format_strings[['n_counts']]$format_string, "a")) {
# Replace the flag with however many xs
if (str_detect(format_strings[['n_counts']]$format_string, "a|A")) {
# Replace 'a' with appropriate 'x'
replaced_string <- str_replace(format_strings[['n_counts']]$format_string, "a",
paste(rep("x", n_width), collapse = ""))
# Replace 'A' with appropriate 'X'
replaced_string <- str_replace(replaced_string, "A",
paste(rep("X", n_width), collapse = ""))

# Make a new f_str and replace the old one
format_strings[['n_counts']] <- f_str(replaced_string, !!!format_strings$n_counts$vars)
Expand Down
Loading

0 comments on commit b9011de

Please sign in to comment.