Intelligently converts column types in a dataset based on their content. Handles character-to-factor conversion, binary numeric variables, and various NA representations. Preserves variable labels from SAS/labelled data.
Usage
r_data_types(
dataset,
factor_size = 10,
skip_vars = NULL,
binary_factor = FALSE,
use_value_labels = FALSE
)Arguments
- dataset
A data frame, tibble, data.table, or similar tabular object
- factor_size
Integer threshold for factor conversion. Numeric variables with fewer than this many unique values (but more than 2) will be converted to factors. Must be between 2 and 50. Default is 10.
- skip_vars
Character vector of column names to exclude from conversion. These columns will remain unchanged. Default is NULL (convert all columns).
- binary_factor
Logical. If TRUE, binary variables are converted to factors instead of logical. Default is FALSE (convert to logical).
- use_value_labels
Logical. If TRUE, a column carrying value labels – what haven reads from a SAS numeric-plus-format variable – is converted through
to_factor, so the level text is kept. If FALSE the value labels are dropped and the numeric codes are converted instead. Default is FALSE, which warns once per session; the default becomes TRUE in a later release.
Value
An object of the same class as dataset with columns
converted according to the function's rules. Variable labels are
preserved. The result carries a per-column conversion report, read with
type_conversion_report.
Details
Each column is converted by the first rule that matches, in this order:
When
use_value_labels = TRUEand the column carries value labels, they become the factor levels. This runs ahead of every rule below: a declared type is not subject to a threshold on distinct values.Character strings "NA", "na", "Na" and "nA" become
NA.Numeric or integer columns with exactly 2 distinct values become logical, or factors when
binary_factor = TRUE– but only when the two values are 0 and 1. Any other 2-distinct-value coding (a SAS-style 1/2, say) becomes a factor outright, regardless ofbinary_factor:as.logical()maps every nonzero code toTRUE, so a 1/2 column would otherwise becomeTRUEfor every row and silently lose one of its two categories.Remaining character columns become factors.
Numeric columns with 3 to
factor_sizedistinct values become factors.Logical columns become factors when
binary_factor = TRUE.
Date, POSIXct, and POSIXlt columns are never altered by type conversion.
Which rule fired on which column is recorded on the result and read back
with type_conversion_report.
See also
type_conversion_report for the record of which rule
fired on which column.
Examples
# Basic usage with sample data
dta <- sample_data(n = 100)
str(dta) # Original types
#> 'data.frame': 100 obs. of 7 variables:
#> $ id : int 1 2 3 4 5 6 7 8 9 10 ...
#> ..- attr(*, "label")= chr "Patient Identifier"
#> $ boolean: int 2 1 1 1 1 2 1 1 2 2 ...
#> ..- attr(*, "label")= chr "Binary Indicator"
#> $ logical: chr "T" "F" "F" "F" ...
#> ..- attr(*, "label")= chr "Logical Status"
#> $ f_real : num 0.572 0.373 0.373 0.356 0.572 ...
#> ..- attr(*, "label")= chr "Random Uniform Value"
#> $ float : num -0.6179 0.2207 1.1279 1.8135 -0.0838 ...
#> ..- attr(*, "label")= chr "Random Normal Value"
#> $ char : chr "male" "female" "female" "female" ...
#> ..- attr(*, "label")= chr "Gender"
#> $ factor : Factor w/ 5 levels "C1","C2","C3",..: 2 4 5 2 3 3 2 2 4 2 ...
#> ..- attr(*, "label")= chr "Category Group"
dta_converted <- r_data_types(dta, use_value_labels = FALSE)
str(dta_converted) # Converted types
#> 'data.frame': 100 obs. of 7 variables:
#> $ id : int 1 2 3 4 5 6 7 8 9 10 ...
#> ..- attr(*, "label")= chr "Patient Identifier"
#> $ boolean: Factor w/ 2 levels "1","2": 2 1 1 1 1 2 1 1 2 2 ...
#> ..- attr(*, "label")= chr "Binary Indicator"
#> $ logical: Factor w/ 2 levels "F","T": 2 1 1 1 1 2 1 1 2 2 ...
#> ..- attr(*, "label")= chr "Logical Status"
#> $ f_real : Factor w/ 9 levels "0.0729944417253137",..: 6 5 5 4 6 6 9 7 8 2 ...
#> ..- attr(*, "label")= chr "Random Uniform Value"
#> $ float : num -0.6179 0.2207 1.1279 1.8135 -0.0838 ...
#> ..- attr(*, "label")= chr "Random Normal Value"
#> $ char : Factor w/ 2 levels "female","male": 2 1 1 1 1 1 2 2 2 2 ...
#> ..- attr(*, "label")= chr "Gender"
#> $ factor : Factor w/ 5 levels "C1","C2","C3",..: 2 4 5 2 3 3 2 2 4 2 ...
#> ..- attr(*, "label")= chr "Category Group"
#> - attr(*, "hvti_type_conversion")='data.frame': 7 obs. of 6 variables:
#> ..$ variable : chr [1:7] "id" "boolean" "logical" "f_real" ...
#> ..$ storage_in : chr [1:7] "integer" "integer" "character" "numeric" ...
#> ..$ rule : chr [1:7] "unchanged" "n_distinct_factor" "character_factor" "n_distinct_factor" ...
#> ..$ level_source: chr [1:7] NA "inference" "inference" "inference" ...
#> ..$ n_levels : int [1:7] NA 2 2 9 NA 2 5
#> ..$ storage_out : chr [1:7] "integer" "factor" "factor" "factor" ...
# Real data example with mtcars
str(datasets::mtcars$vs) # numeric (0/1)
#> num [1:32] 0 0 1 1 0 1 0 1 1 1 ...
mtcars_converted <- r_data_types(datasets::mtcars,
use_value_labels = FALSE)
str(mtcars_converted$vs) # logical (FALSE/TRUE)
#> logi [1:32] FALSE FALSE TRUE TRUE FALSE TRUE ...
#> - attr(*, "label")= chr "vs"
# Skip specific columns
mtcars_partial <- r_data_types(datasets::mtcars,
skip_vars = c("vs", "am"),
use_value_labels = FALSE)
str(mtcars_partial$vs) # Still numeric (unchanged)
#> num [1:32] 0 0 1 1 0 1 0 1 1 1 ...
#> - attr(*, "label")= chr "vs"
# Control factor creation threshold
mtcars_strict <- r_data_types(datasets::mtcars, factor_size = 5,
use_value_labels = FALSE)
# Keep binary variables as factors
mtcars_factors <- r_data_types(datasets::mtcars, binary_factor = TRUE,
use_value_labels = FALSE)
str(mtcars_factors$vs) # Factor instead of logical
#> Factor w/ 2 levels "FALSE","TRUE": 1 1 2 2 1 2 1 2 2 2 ...
#> - attr(*, "label")= chr "vs"
# Keep the level text of a SAS formatted variable
disp <- haven::labelled(c(1, 2, 1, 3),
labels = c(Home = 1, Rehab = 2, SNF = 3),
label = "Discharge disposition")
converted <- r_data_types(data.frame(disp = disp), use_value_labels = TRUE)
levels(converted$disp)
#> [1] "Home" "Rehab" "SNF"
type_conversion_report(converted)
#> variable storage_in rule level_source n_levels storage_out
#> 1 disp haven_labelled value_labels value labels 3 factor