visualizeR/R/reorder.R
2025-01-19 20:06:31 +01:00

104 lines
No EOL
3 KiB
R

#' Reorder a Data Frame Factoring Column x
#'
#' @param df A data frame to be reordered.
#' @param x A character scalar specifying the column to be reordered.
#' @param y A character scalar specifying the column to order by if ordering by values.
#' @param group A character scalar specifying the grouping column (optional).
#' @param order A character scalar specifying the order type (one of "none", "y", "grouped"). See details.
#' @param dir_order A logical scalar specifying whether to flip the order.
#'
#' @details Ordering takes the following possible values:
#'
#' * "none": No reordering.
#' * "y": Order by values of y.
#' * "grouped_y": Order by values of y and group.
#' * "x": Order alphabetically by x.
#' * "grouped_x": Order alphabetically by x and group.
#'
#'
#' @return The reordered data frame.
#'
#' @examples
#' # Example usage
#' df <- data.frame(col1 = c("b", "a", "c"), col2 = c(10, 25, 3))
#' reorder(df, "col1", "col2")
#' @export
reorder <- function(df, x, y, group = "", order = "y", dir_order = 1){
#------ Checks
# df is a data frame
checkmate::assert_data_frame(df)
# df is data.table, if not convert
if (!checkmate::test_data_table(df)) {
rlang::warn("Converting df to data.table.")
data.table::setDT(df)
}
# x and y are character scalar and in df
checkmate::assert_character(x, len = 1)
checkmate::assert_character(y, len = 1)
checkmate::assert_subset(x, colnames(df))
checkmate::assert_subset(y, colnames(df))
# group is character scalar and in df if not empty
checkmate::assert_character(group, len = 1)
if (group != "") checkmate::assert_subset(group, colnames(df))
# order is a character scalar in c("none", "y", "grouped")
checkmate::assert_choice(order, c("none", "y", "grouped_y", "x", "grouped_x"))
# dir_order is 1 or -1 (numeric scalar)
checkmate::assert_subset(dir_order, c(1, -1))
#------ Reorder
# droplevels first
if (is.factor(df[[x]])) {
df[, (x) := droplevels(get(x))]
}
# reording options
if (order == "y") {
data.table::setorderv(df, y, order = dir_order)
df[, (x) := forcats::fct_inorder(get(x))]
} else if (order == "grouped" && group == "") {
rlang::warn("Group is empty. Ordering by y only.")
data.table::setorderv(df, y, order = dir_order)
df[, (x) := forcats::fct_inorder(get(x))]
} else if (order == "grouped_y" && group != "") {
data.table::setorderv(df, c(group, y), order = dir_order)
df[, (x) := forcats::fct_inorder(get(x))]
} else if (order == "x") {
data.table::setorderv(df, x, order = dir_order)
df[, (x) := forcats::fct_inorder(get(x))]
} else if (order == "grouped_x" && group != "") {
data.table::setorderv(df, c(group, x), order = dir_order)
df[, (x) := forcats::fct_inorder(get(x))]
} else if (order == "grouped_x" && group == "") {
rlang::warn("Group is empty. Ordering by x only.")
data.table::setorderv(df, x, order = dir_order)
df[, (x) := forcats::fct_inorder(get(x))]
}
return(df)
}