1#' Missing values 2#' 3#' @description 4#' 5#' \Sexpr[results=rd, stage=render]{rlang:::lifecycle("questioning")} 6#' 7#' Missing values are represented in R with the general symbol 8#' `NA`. They can be inserted in almost all data containers: all 9#' atomic vectors except raw vectors can contain missing values. To 10#' achieve this, R automatically converts the general `NA` symbol to a 11#' typed missing value appropriate for the target vector. The objects 12#' provided here are aliases for those typed `NA` objects. 13#' 14#' 15#' @details 16#' 17#' Typed missing values are necessary because R needs sentinel values 18#' of the same type (i.e. the same machine representation of the data) 19#' as the containers into which they are inserted. The official typed 20#' missing values are `NA_integer_`, `NA_real_`, `NA_character_` and 21#' `NA_complex_`. The missing value for logical vectors is simply the 22#' default `NA`. The aliases provided in rlang are consistently named 23#' and thus simpler to remember. Also, `na_lgl` is provided as an 24#' alias to `NA` that makes intent clearer. 25#' 26#' Since `na_lgl` is the default `NA`, expressions such as `c(NA, NA)` 27#' yield logical vectors as no data is available to give a clue of the 28#' target type. In the same way, since lists and environments can 29#' contain any types, expressions like `list(NA)` store a logical 30#' `NA`. 31#' 32#' 33#' @section Life cycle: 34#' 35#' These shortcuts might be moved to the vctrs package at some 36#' point. This is why they are marked as questioning. 37#' 38#' @keywords internal 39#' @examples 40#' typeof(NA) 41#' typeof(na_lgl) 42#' typeof(na_int) 43#' 44#' # Note that while the base R missing symbols cannot be overwritten, 45#' # that's not the case for rlang's aliases: 46#' na_dbl <- NA 47#' typeof(na_dbl) 48#' @name missing 49NULL 50 51#' @rdname missing 52#' @export 53na_lgl <- NA 54#' @rdname missing 55#' @export 56na_int <- NA_integer_ 57#' @rdname missing 58#' @export 59na_dbl <- NA_real_ 60#' @rdname missing 61#' @export 62na_chr <- NA_character_ 63#' @rdname missing 64#' @export 65na_cpl <- NA_complex_ 66 67 68#' Test for missing values 69#' 70#' @description 71#' 72#' \Sexpr[results=rd, stage=render]{rlang:::lifecycle("questioning")} 73#' 74#' `are_na()` checks for missing values in a vector and is equivalent 75#' to [base::is.na()]. It is a vectorised predicate, meaning that its 76#' output is always the same length as its input. On the other hand, 77#' `is_na()` is a scalar predicate and always returns a scalar 78#' boolean, `TRUE` or `FALSE`. If its input is not scalar, it returns 79#' `FALSE`. Finally, there are typed versions that check for 80#' particular [missing types][missing]. 81#' 82#' 83#' @details 84#' 85#' The scalar predicates accept non-vector inputs. They are equivalent 86#' to [is_null()] in that respect. In contrast the vectorised 87#' predicate `are_na()` requires a vector input since it is defined 88#' over vector values. 89#' 90#' @param x An object to test 91#' 92#' @section Life cycle: 93#' 94#' These functions might be moved to the vctrs package at some 95#' point. This is why they are marked as questioning. 96#' 97#' @keywords internal 98#' @examples 99#' # are_na() is vectorised and works regardless of the type 100#' are_na(c(1, 2, NA)) 101#' are_na(c(1L, NA, 3L)) 102#' 103#' # is_na() checks for scalar input and works for all types 104#' is_na(NA) 105#' is_na(na_dbl) 106#' is_na(character(0)) 107#' 108#' # There are typed versions as well: 109#' is_lgl_na(NA) 110#' is_lgl_na(na_dbl) 111#' @export 112are_na <- function(x) { 113 if (!is_atomic(x)) { 114 abort("`x` must be an atomic vector") 115 } 116 is.na(x) 117} 118#' @rdname are_na 119#' @export 120is_na <- function(x) { 121 is_scalar_vector(x) && is.na(x) 122} 123 124#' @rdname are_na 125#' @export 126is_lgl_na <- function(x) { 127 identical(x, na_lgl) 128} 129#' @rdname are_na 130#' @export 131is_int_na <- function(x) { 132 identical(x, na_int) 133} 134#' @rdname are_na 135#' @export 136is_dbl_na <- function(x) { 137 identical(x, na_dbl) 138} 139#' @rdname are_na 140#' @export 141is_chr_na <- function(x) { 142 identical(x, na_chr) 143} 144#' @rdname are_na 145#' @export 146is_cpl_na <- function(x) { 147 identical(x, na_cpl) 148} 149