R - Factors
R - Factors
Section titled “R - Factors”Factors are a special data type in R used to handle categorical data. They are essential for statistical modeling and data visualization, as they allow you to define a fixed set of categories, known as levels. Factors can be created from both character and integer vectors and are particularly useful for columns with a limited number of unique values, such as "Male"/"Female", or "Low"/"Medium"/"High".
Factors are created using the factor() function, which takes a vector as its primary input. Understanding factors is crucial for both base R and modern data analysis workflows.
Important Note on Modern R: Since R version 4.0.0 (released in 2020), the default behavior of functions like data.frame() and read.csv() has changed. They no longer automatically convert character vectors into factors. The old default was stringsAsFactors = TRUE, but the new default is stringsAsFactors = FALSE. This means you now usually need to create factors explicitly, which gives you more control over your data.
Creating a Factor
Section titled “Creating a Factor”Let’s create a factor from a character vector. Notice how the output displays the original data along with the unique Levels.
# Create a character vectordirections <- c("East", "West", "East", "North", "North", "East", "West")
# Check its class and if it's a factorprint(directions)cat("Is it a factor? ", is.factor(directions), "\n")
# Apply the factor() function to convert itfactor_directions <- factor(directions)
# Check the resultprint(factor_directions)cat("Is it a factor now? ", is.factor(factor_directions), "\n")When you run the code above, you get the following output:
[1] "East" "West" "East" "North" "North" "East" "West"Is it a factor? FALSE
[1] East West East North North East WestLevels: East North WestIs it a factor now? TRUEFactors in a Data Frame
Section titled “Factors in a Data Frame”As mentioned, modern R does not automatically create factors from strings. Let’s see this in action and then explicitly convert the column.
# Create vectors for our data frameheight <- c(132, 151, 162, 139, 166, 147, 122)weight <- c(48, 49, 66, 53, 67, 52, 40)gender <- c("male", "male", "female", "female", "male", "female", "male")
# Create the data frameemployee_data <- data.frame(height, weight, gender)print(employee_data)
# Test if the gender column is a factor (it won't be by default)cat("Is 'gender' a factor by default? ", is.factor(employee_data$gender), "\n")cat("What is the class of 'gender'? ", class(employee_data$gender), "\n\n")
# Now, let's convert it to a factoremployee_data$gender <- factor(employee_data$gender)
# Check againcat("Is 'gender' a factor now? ", is.factor(employee_data$gender), "\n")
# Print the gender column to see the levelsprint(employee_data$gender)Executing this code demonstrates the modern workflow:
height weight gender1 132 48 male2 151 49 male3 162 66 female4 139 53 female5 166 67 male6 147 52 female7 122 40 maleIs 'gender' a factor by default? FALSEWhat is the class of 'gender'? character
Is 'gender' a factor now? TRUE[1] male male female female male female maleLevels: female maleManaging Factor Levels
Section titled “Managing Factor Levels”The order of levels in a factor defaults to alphabetical. You can change this order, which is very important for visualizations and modeling (e.g., setting a baseline category).
Base R Approach
Section titled “Base R Approach”You can re-apply the factor() function with the levels argument to specify the desired order.
# Our original factor from beforedirections <- c("East", "West", "East", "North")factor_directions <- factor(directions)cat("Original Factor Levels:\n")print(factor_directions)
# Reorder the levelsordered_factor <- factor(factor_directions, levels = c("North", "East", "West"))cat("\nReordered Factor Levels:\n")print(ordered_factor)The output shows the new level ordering:
Original Factor Levels:[1] East West East NorthLevels: East North West
Reordered Factor Levels:[1] East West East NorthLevels: North East WestModern Tidyverse Approach with forcats
Section titled “Modern Tidyverse Approach with forcats”The forcats package (part of the tidyverse) provides a suite of intuitive functions for working with factors. The fct_relevel() function is excellent for reordering.
# First, ensure you have tidyverse installed: install.packages("tidyverse")library(forcats)
# Using the same factorfactor_directions <- factor(c("East", "West", "East", "North"))
# Use fct_relevel to bring "North" to the frontforcats_reordered <- fct_relevel(factor_directions, "North")
cat("Reordered with forcats:\n")print(forcats_reordered)
# You can specify the full order as wellforcats_reordered_full <- fct_relevel(factor_directions, "North", "East", "West")print(levels(forcats_reordered_full))The forcats approach is often more readable and powerful for complex manipulations.
Reordered with forcats:[1] East West East NorthLevels: North East West[1] "North" "East" "West"Generating Factor Levels
Section titled “Generating Factor Levels”The gl() function (Generate Levels) is a handy tool for creating balanced, repetitive factor structures, often used in designing experiments or creating sample data.
Syntax
Section titled “Syntax”gl(n, k, labels)- n: an integer specifying the number of levels.
- k: an integer specifying the number of replications for each level.
- labels: a character vector providing labels for the factor levels.
Example
Section titled “Example”Let’s generate a factor with 3 levels, each repeated 4 times.
v <- gl(3, 4, labels = c("Tampa", "Seattle", "Boston"))print(v)The output clearly shows the generated factor:
[1] Tampa Tampa Tampa Tampa Seattle Seattle Seattle Seattle Boston Boston Boston BostonLevels: Tampa Seattle Boston