#' @title Check whether string, list or vector is empty
#' @name is_empty
#' @description This function checks whether a string or character vector (of
#' length 1), a list or any vector (numeric, atomic) is empty or not.
#'
#'
#' @param x String, character vector, list, data.frame or numeric vector or factor.
#' @param first.only Logical, if \code{FALSE} and \code{x} is a character
#' vector, each element of \code{x} will be checked if empty. If
#' \code{TRUE}, only the first element of \code{x} will be checked.
#' @param all.na.empty Logical, if \code{x} is a vector with \code{NA}-values
#' only, \code{is_empty} will return \code{FALSE} if \code{all.na.empty = FALSE},
#' and will return \code{TRUE} if \code{all.na.empty = TRUE} (default).
#' @return Logical, \code{TRUE} if \code{x} is a character vector or string and
#' is empty, \code{TRUE} if \code{x} is a vector or list and of length 0,
#' \code{FALSE} otherwise.
#'
#' @note \code{NULL}- or \code{NA}-values are also considered as "empty" (see
#' 'Examples') and will return \code{TRUE}, unless \code{all.na.empty==FALSE}.
#'
#' @examples
#' is_empty("test")
#' is_empty("")
#' is_empty(NA)
#' is_empty(NULL)
#'
#' # string is not empty
#' is_empty(" ")
#'
#' # however, this trimmed string is
#' is_empty(trim(" "))
#'
#' # numeric vector
#' x <- 1
#' is_empty(x)
#' x <- x[-1]
#' is_empty(x)
#'
#' # check multiple elements of character vectors
#' is_empty(c("", "a"))
#' is_empty(c("", "a"), first.only = FALSE)
#'
#' # empty data frame
#' d <- data.frame()
#' is_empty(d)
#'
#' # empty list
#' is_empty(list(NULL))
#'
#' # NA vector
#' x <- rep(NA,5)
#' is_empty(x)
#' is_empty(x, all.na.empty = FALSE)
#' @export
is_empty <- function(x, first.only = TRUE, all.na.empty = TRUE) {
# do we have a valid vector?
if (!is.null(x)) {
# if it's a character, check if we have only one element in that vector
if (is.character(x)) {
# characters may also be of length 0
if (length(x) == 0) return(TRUE)
# else, check all elements of x
zero_len <- nchar(x) == 0
# return result for multiple elements of character vector
if (first.only) {
zero_len <- .is_true(zero_len[1])
if (length(x) > 0) x <- x[1]
} else {
return(unname(zero_len))
}
# we have a non-character vector here. check for length
} else if (is.list(x)) {
x <- purrr::compact(x)
zero_len <- length(x) == 0
} else {
zero_len <- length(x) == 0
}
}
any(is.null(x) || zero_len || (all.na.empty && all(is.na(x))))
}
.is_true <- function(x) {
is.logical(x) && length(x) == 1L && !is.na(x) && x
}
#' @title Return or remove variables or observations that are completely missing
#' @name empty_cols
#'
#' @description These functions check which rows or columns of a data frame completely
#' contain missing values, i.e. which observations or variables
#' completely have missing values, and either 1) returns their
#' indices; or 2) removes them from the data frame.
#'
#'
#' @param x A data frame.
#'
#' @return For \code{empty_cols} and \code{empty_rows}, a numeric (named) vector
#' with row or column indices of those variables that completely have
#' missing values.
#' \cr \cr
#' For \code{remove_empty_cols} and \code{remove_empty_rows}, a
#' data frame with "empty" columns or rows removed.
#'
#' @examples
#' tmp <- data.frame(a = c(1, 2, 3, NA, 5),
#' b = c(1, NA, 3, NA , 5),
#' c = c(NA, NA, NA, NA, NA),
#' d = c(1, NA, 3, NA, 5))
#'
#' tmp
#'
#' empty_cols(tmp)
#' empty_rows(tmp)
#'
#' remove_empty_cols(tmp)
#' remove_empty_rows(tmp)
#'
#' @export
empty_cols <- function(x) {
if ((!is.matrix(x) && !is.data.frame(x)) || ncol(x) < 2)
vector("numeric")
else
which(colSums(is.na(x)) == nrow(x))
}
#' @rdname empty_cols
#' @export
empty_rows <- function(x) {
if ((!is.matrix(x) && !is.data.frame(x)) || nrow(x) < 2)
vector("numeric")
else
which(rowSums(is.na(x)) == ncol(x))
}
#' @rdname empty_cols
#' @export
remove_empty_cols <- function(x) {
# check if we have any empty columns at all
ec <- empty_cols(x)
# if yes, removing works, else an empty df would be returned
if (!sjmisc::is_empty(ec))
dplyr::select(x, !! -ec)
else
x
}
#' @rdname empty_cols
#' @export
remove_empty_rows <- function(x) {
# check if we have any empty rows at all
er <- empty_rows(x)
# if yes, removing works, else an empty df would be returned
if (!sjmisc::is_empty(er))
dplyr::slice(x, !! -er)
else
x
}
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.