104 lines
No EOL
3 KiB
R
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)
|
|
|
|
}
|
|
|