#' @title Rotate a data frame
#' @name rotate_df
#' @description This function rotates a data frame, i.e. columns become rows
#' and vice versa.
#'
#' @param x A data frame.
#' @param rn Character vector (optional). If not \code{NULL}, the data frame's
#' rownames will be added as (first) column to the output, with
#' \code{rn} being the name of this column.
#' @param cn Logical (optional), if \code{TRUE}, the values of the first column
#' in \code{x} will be used as column names in the rotated data frame.
#'
#' @return A (rotated) data frame.
#'
#' @examples
#' x <- mtcars[1:3, 1:4]
#' rotate_df(x)
#' rotate_df(x, rn = "property")
#'
#' # use values in 1. column as column name
#' rotate_df(x, cn = TRUE)
#' rotate_df(x, rn = "property", cn = TRUE)
#'
#' # also works on list-results
#' library(purrr)
#'
#' dat <- mtcars[1:3, 1:4]
#' tmp <- purrr::map(dat, function(x) {
#' sdev <- stats::sd(x, na.rm = TRUE)
#' ulsdev <- mean(x, na.rm = TRUE) + c(-sdev, sdev)
#' names(ulsdev) <- c("lower_sd", "upper_sd")
#' ulsdev
#' })
#' tmp
#' as.data.frame(tmp)
#' rotate_df(tmp)
#'
#' tmp <- purrr::map_df(dat, function(x) {
#' sdev <- stats::sd(x, na.rm = TRUE)
#' ulsdev <- mean(x, na.rm = TRUE) + c(-sdev, sdev)
#' names(ulsdev) <- c("lower_sd", "upper_sd")
#' ulsdev
#' })
#' tmp
#' rotate_df(tmp)
#' @export
rotate_df <- function(x, rn = NULL, cn = FALSE) {
# check if first column has column names
# that should be used for rotated df
if (cn) {
cnames <- x[[1]]
x <- dplyr::select(x, -1)
} else
cnames <- NULL
# copy attributes
a <- attributes(x)
# rotate data frame for 90°
x <- x %>%
as.data.frame() %>%
t() %>%
as.data.frame()
# add column names, if requested
if (!is.null(cnames)) {
# check if we have correct length of column names
if (length(cnames) != ncol(x))
warning("Length of provided column names does not match number of columns. No column names changed.", call. = FALSE)
else
colnames(x) <- cnames
}
# add rownames as column, if requested
if (!is.null(rn)) x <- rownames_as_column(x, var = rn)
# add back attributes. therefore, delete the common attributes, like class etc.
# and then add attributes to our final df
# a[c("names", "row.names", "class", "dim", "dimnames")] <- NULL
a[names(a) %in% names(attributes(x))] <- NULL
attributes(x) <- c(attributes(x), a)
x
}
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.