Skip to contents

if_else() is a survey-aware version of dplyr::if_else() that applies a binary condition element-wise: true values are used where condition is TRUE, false values where it is FALSE, and missing values where it is NA.

Compared to base ifelse(), this function is stricter about types: true, false, and missing must be compatible and will be cast to their common type.

When any of .label, .value_labels, or .description are supplied, output label metadata is written to @metadata after mutate(). When none of these arguments are used, the output is identical to dplyr::if_else().

For more than two conditions, see case_when().

Usage

if_else(
  condition,
  true,
  false,
  missing = NULL,
  ...,
  ptype = NULL,
  .label = NULL,
  .value_labels = NULL,
  .description = NULL
)

Arguments

condition

A logical vector.

true, false

Vectors to use for TRUE and FALSE values of condition. Both are recycled to the size of condition and cast to their common type.

missing

If not NULL, used as the value for NA values of condition. Follows the same size and type rules as true and false.

...

These dots are for future extensions and must be empty.

ptype

An optional prototype declaring the desired output type. Overrides the common type of true, false, and missing.

.label

character(1) or NULL. Variable label stored in @metadata@variable_labels after mutate().

.value_labels

Named vector or NULL. Value labels stored in @metadata@value_labels. Names are the label strings; values are the data values.

.description

character(1) or NULL. Plain-language description of how the variable was created. Stored in @metadata@transformations[[col]]$description after mutate().

Value

A vector the same size as condition and the common type of true, false, and missing. If .label or .value_labels are supplied, returns a haven_labelled vector; otherwise returns the same type as the common type of the inputs.

See also

Other recoding: case_when(), na_if(), recode_values(), replace_values(), replace_when()

Examples

library(surveycore)
library(surveytidy)

# create the survey design
ns_wave1_svy <- as_survey_nonprob(ns_wave1, weights = weight)

# basic if_else — identical to dplyr::if_else()
new <- ns_wave1_svy |>
  mutate(senior = if_else(age >= 65, "Senior (65+)", "Non-senior")) |>
  select(age, senior)

# by default, no metadata is attached
new
#> 
#> ── Survey Design ───────────────────────────────────────────────────────────────
#> <survey_nonprob> (non-probability) [experimental]
#> Sample size: 6422
#> 
#> # A tibble: 6,422 × 2
#>      age senior    
#>    <dbl> <chr>     
#>  1    37 Non-senior
#>  2    45 Non-senior
#>  3    24 Non-senior
#>  4    26 Non-senior
#>  5    60 Non-senior
#>  6    55 Non-senior
#>  7    37 Non-senior
#>  8    46 Non-senior
#>  9    60 Non-senior
#> 10    32 Non-senior
#> # ℹ 6,412 more rows
#> 
#>  Design variables preserved but hidden: weight.
#>  Use `print(x, full = TRUE)` to show all variables.
new@metadata
#> <surveycore::survey_metadata>
#>  @ variable_labels  :List of 2
#>  .. $ age   : chr "What is your age? Provided by LUCID. Response is an integer value 18 or ..."
#>  .. $ weight: chr "Survey weight, continuous value from 0-5"
#>  @ value_labels     : Named list()
#>  @ question_prefaces: Named list()
#>  @ notes            : list()
#>  @ universe         : list()
#>  @ missing_codes    : list()
#>  @ sata             : list()
#>  @ transformations  :List of 1
#>  .. $ senior: chr "if_else(age >= 65, \"Senior (65+)\", \"Non-senior\")"
#>  @ weighting_history: list()

# use missing = to specify the output value when condition is NA
new <- ns_wave1_svy |>
  mutate(
    dem = if_else(
      pid3 == 1,
      "Democrat",
      "Non-Democrat",
      missing = "Unknown"
    )
  ) |>
  select(pid3, dem)

new
#> 
#> ── Survey Design ───────────────────────────────────────────────────────────────
#> <survey_nonprob> (non-probability) [experimental]
#> Sample size: 6422
#> 
#> # A tibble: 6,422 × 2
#>     pid3 dem         
#>    <dbl> <chr>       
#>  1     1 Democrat    
#>  2     1 Democrat    
#>  3     1 Democrat    
#>  4     3 Non-Democrat
#>  5     2 Non-Democrat
#>  6     1 Democrat    
#>  7     4 Non-Democrat
#>  8     2 Non-Democrat
#>  9     2 Non-Democrat
#> 10     1 Democrat    
#> # ℹ 6,412 more rows
#> 
#>  Design variables preserved but hidden: weight.
#>  Use `print(x, full = TRUE)` to show all variables.

# attach a variable label via .label
new <- ns_wave1_svy |>
  mutate(
    senior = if_else(
      age >= 65,
      "Senior (65+)",
      "Non-senior",
      .label = "Senior citizen (age 65+)"
    )
  ) |>
  select(age, senior)

new@metadata@variable_labels
#> $age
#> [1] "What is your age? Provided by LUCID. Response is an integer value 18 or ..."
#> 
#> $weight
#> [1] "Survey weight, continuous value from 0-5"
#> 
#> $senior
#> [1] "Senior citizen (age 65+)"
#> 

# use integer codes and document them with value labels
new <- ns_wave1_svy |>
  mutate(
    senior = if_else(
      age >= 65,
      true = 1L,
      false = 0L,
      .label = "Senior citizen (age 65+)",
      .value_labels = c("Senior (65+)" = 1, "Non-senior" = 0)
    )
  ) |>
  select(age, senior)

new@metadata@value_labels
#> $senior
#> Senior (65+)   Non-senior 
#>            1            0 
#> 

# attach a plain-language description of the transformation
new <- ns_wave1_svy |>
  mutate(
    senior = if_else(
      age >= 65,
      "Senior (65+)",
      "Non-senior",
      .label = "Senior citizen (age 65+)",
      .description = paste(
        "age >= 65 coded as 'Senior (65+)';",
        "everyone else as 'Non-senior'."
      )
    )
  ) |>
  select(age, senior)

new@metadata@transformations
#> $senior
#> $senior$fn
#> [1] "if_else"
#> 
#> $senior$source_cols
#> [1] "age"
#> 
#> $senior$expr
#> [1] "if_else(age >= 65, \"Senior (65+)\", \"Non-senior\", .label = \"Senior citizen (age 65+)\", "
#> [2] "    .description = paste(\"age >= 65 coded as 'Senior (65+)';\", "                           
#> [3] "        \"everyone else as 'Non-senior'.\"))"                                                
#> 
#> $senior$output_type
#> [1] "vector"
#> 
#> $senior$description
#> [1] "age >= 65 coded as 'Senior (65+)'; everyone else as 'Non-senior'."
#> 
#>