-
Notifications
You must be signed in to change notification settings - Fork 65
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Closes #2571 transform_range: implement transform_range() #2587
base: main
Are you sure you want to change the base?
Changes from all commits
1ff35a9
ef74268
4d001df
3df0083
e8835f7
2f8aee6
09d1280
065a338
e038f38
b0ec086
8104ca5
6678ede
f9890f8
bce1cb1
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,114 @@ | ||
#' Transform Range | ||
#' | ||
#' Transforms results from the source range to the target range. For example, | ||
#' for transforming source values 1, 2, 3, 4, 5 to 0, 25, 50, 75, 100. | ||
#' | ||
#' @param source A vector of values to be transformed | ||
#' | ||
#' A numeric vector is expected. | ||
#' | ||
#' @param source_range The permitted source range | ||
#' | ||
#' A numeric vector containing two elements is expected, representing the | ||
#' lower and upper bounds of the permitted source range. | ||
#' | ||
#' @param target_range The target range | ||
#' | ||
#' A numeric vector containing two elements is expected, representing the | ||
#' lower and upper bounds of the target range. | ||
#' | ||
#' @param flip_direction Flip direction of the range? | ||
#' | ||
#' The transformed values will be reversed within the target range, e.g. | ||
#' within the range 0 to 100, 25 would be reversed to 75. | ||
#' | ||
#' *Permitted Values*: `TRUE`, `FALSE` | ||
#' | ||
#' @param outside_range Handling of values outside the source range | ||
#' | ||
#' Values outside the source range (`source_range`) are transformed to `NA`. | ||
#' | ||
#' If `"warning"` or `"error"` is specified, a warning or error is issued if | ||
#' `source` includes any values outside the source range. | ||
#' | ||
#' *Permitted Values*: `"NA"`, `"warning"`, `"error"` | ||
#' | ||
#' @details Returns the values of `source` linearly transformed from the source | ||
#' range (`source_range`) to the target range (`target_range`). Values outside | ||
#' the source range are set to `NA`. | ||
#' | ||
#' @return The source linearly transformed to the target range | ||
#' | ||
#' @keywords com_bds_findings | ||
#' | ||
#' @family com_bds_findings | ||
#' | ||
#' @export | ||
#' | ||
#' @examples | ||
#' transform_range( | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Please could you add another example before this one that doesn't flip the range? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes, example added |
||
#' source = c(1, 4, 3, 6, 5), | ||
#' source_range = c(1, 5), | ||
#' target_range = c(0, 100) | ||
#' ) | ||
#' | ||
#' transform_range( | ||
#' source = c(1, 4, 3, 6, 5), | ||
#' source_range = c(1, 5), | ||
#' target_range = c(0, 100), | ||
#' flip_direction = TRUE | ||
#' ) | ||
transform_range <- function(source, | ||
source_range, | ||
target_range, | ||
flip_direction = FALSE, | ||
outside_range = "NA") { | ||
# Function argument checks | ||
assert_numeric_vector(source) | ||
assert_numeric_vector(source_range, length = 2) | ||
assert_numeric_vector(target_range, length = 2) | ||
assert_logical_scalar(flip_direction) | ||
assert_character_scalar(outside_range, values = c("NA", "error", "warning")) | ||
|
||
outsider <- !(between(source, source_range[[1]], source_range[[2]]) | is.na(source)) | ||
if (any(outsider)) { | ||
outside_index <- which(outsider) | ||
outside_value <- source[outsider] | ||
source <- if_else(outsider, NA, source) | ||
msg <- c( | ||
paste( | ||
"{.arg source} contains values outside the range of {.val {source_range[[1]]}}", | ||
"to {.val {source_range[[2]]}}:" | ||
), | ||
paste0("source[[", outside_index, "]] = {.val {", outside_value, "}}") | ||
) | ||
if (outside_range == "warning") { | ||
cli_warn( | ||
msg, | ||
class = c("outside_source_range", "assert-admiral"), | ||
outside_index = outside_index, | ||
outside_value = outside_value | ||
) | ||
} else if (outside_range == "error") { | ||
cli_abort( | ||
msg, | ||
class = c("outside_source_range", "assert-admiral"), | ||
outside_index = outside_index, | ||
outside_value = outside_value | ||
) | ||
} | ||
} | ||
|
||
# Computation | ||
range_constant <- min(target_range) - min(source_range) | ||
range_coefficient <- (max(target_range) - min(target_range)) / | ||
(max(source_range) - min(source_range)) | ||
|
||
target <- (source + range_constant) * range_coefficient | ||
|
||
if (flip_direction == TRUE) { | ||
target <- max(target_range) - target | ||
} | ||
|
||
target | ||
} |
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A new type of function to add to our list!?! https://pharmaverse.github.io/admiraldev/dev/articles/programming_strategy.html#function-names
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No, it's a computation. I.e., it is covered by
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
should we add
transform_
so developers know they can use that as a verb?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Then we would need to add
convert_
andimpute_
as well.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would be happy with that!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
OK, I have created an issue in admiraldev (pharmaverse/admiraldev#472).