R
Completed
-
Section 1: Getting Started
-
Section 2: Core Syntax
-
Section 3: Data Structures
-
Section 4: Data Manipulation
-
Section 5: Visualization and Statistics
-
Section 6: Advanced R
-
Section 7: Practical Projects
-
Section 8: Interview Practice
-
Section 9: More Practice Exercises
-
Section 10: Shiny Apps in Depth
-
Section 11: More Data Wrangling
-
Section 12: Tidyverse Deep Dive
-
Section 13: Statistical Modeling Deep Dive
-
Section 14: Machine Learning in R
-
Section 15: R Visualization Deep Dive
-
Section 16: R Package Development Deep Dive
-
Section 17: R for Reproducible Research
-
Section 18: R and Databases
-
Section 19: R Performance Optimization
-
Section 20: Bioinformatics and Specialized R
-
Section 21: More Shiny Practice
-
Section 22: More Practice Exercises
-
Section 23: R Data Structures Deep Dive
-
Section 24: More Interview and Review
-
Section 25: R for Business Analytics
-
Section 26: R Text Mining and NLP
-
Section 27: R Spatial Data Analysis
-
Section 28: R Deep Learning
-
Section 29: Advanced Statistical Techniques
-
Section 30: R Object Systems Deep Dive
-
Section 31: R Environments and Metaprogramming
-
Section 32: R for Finance
-
Section 33: R for Clinical and Health Data
-
Section 34: More Shiny Advanced Practice
-
Section 35: R Data Cleaning Deep Dive
-
Section 36: R Reporting Automation
-
Section 37: More Practical Projects Round 2
-
Section 38: R Ecosystem and Career
-
Section 39: More Visualization Practice
-
Section 40: R for Experimentation
-
Section 41: R for Genomics and Bioinformatics Deep Dive
-
Section 42: R for Marketing Analytics
-
Section 43: R Data Import/Export Deep Dive
-
Section 44: R String Processing Deep Dive
-
Section 45: R for Actuarial and Insurance Analytics
-
Section 46: R Testing and Quality Assurance Deep Dive
-
Section 47: R Version Control and Collaboration
-
Section 48: R Advanced Functional Programming
-
Section 49: R for Supply Chain and Operations
-
Section 50: More Practice Exercises Round 3
-
Section 51: R Dashboards and BI Integration
-
Section 52: R Data Governance and Ethics
-
Section 53: More Modeling Practice
-
Section 54: R Final Capstone Projects
-
Section 55: R for Sports Analytics
-
Section 56: More Interview Practice Round 2
-
Section 57: R Networking and APIs
-
Section 58: R for Environmental Science
-
Section 59: R Notebook and Documentation Practices
-
Section 60: More Data Wrangling Mastery
-
Section 61: R for A/B Testing at Scale
-
Section 62: R Package Ecosystem Deep Dive
28: Apply Family of Functions
I see this mistake constantly, even from developers who have been using R for a while. They try to use apply() to quickly summarize a data frame, and suddenly their numbers vanish or they get a bunch of NA values without any clear error message. Let's look at a typical scenario.
# A simple dataset of employee data
employees <- data.frame(
name = c("Alice", "Bob", "Charlie"),
salary = c(70000, 80000, 90000),
bonus = c(5000, 7000, 6000),
stringsAsFactors = FALSE
)
# I want the average of the numeric columns
column_means <- apply(employees, 2, mean)
print(column_means)
If you run this, you'll likely see a warning about arguments not being numeric, and column_means will be a vector of NAs. Why? Because apply() is designed for matrices. When you pass a data frame to apply(), R coerces the entire thing into a matrix first. Since matrices must have a single data type, and you have a "name" column (strings), R converts every single value in the data frame to a string. You can't calculate the mean of the string "70000".
Stopping the Matrix Coercion Trap
The fix is simple: stop using apply() for data frames. Instead, use lapply() (list-apply) or sapply() (simplified-apply). Since a data frame is technically a list of columns, these functions treat each column as an individual element without forcing a type conversion across the whole table.
# This works because it treats columns as individual lists
means_list <- lapply(employees[, 2:3], mean)
print(means_list)
Now, lapply() always returns a list. That's great for consistency, but it's a pain to read. If you want a cleaner vector output, sapply() is your friend. It tries to "simplify" the result into the most intuitive data structure.
# Returns a named vector instead of a list
means_vector <- sapply(employees[, 2:3], mean)
print(means_vector)
Handling Grouped Data with tapply
Sometimes you don't want the mean of the whole column, but the mean per group. You could write a for-loop to filter the data frame for every unique category, but that's slow and verbose. This is where tapply() (table-apply) comes in. It takes a vector, a grouping factor, and a function.
# Let's add a department column
employees$dept <- c("IT", "HR", "IT")
# Calculate mean salary per department
dept_salaries <- tapply(employees$salary, employees$dept, mean)
print(dept_salaries)
I think of tapply() as the "group by" of the base R apply family. It's incredibly efficient for these kinds of summary tables.
The Swiss Army Knife: mapply
Finally, there's mapply(). While lapply() applies a function to one list, mapply() can apply a function to multiple lists simultaneously. It's a "multivariate" apply. It's less common, but it's a lifesaver when you have two different vectors that need to be passed into a function as separate arguments.
# A custom function that takes two inputs
calc_total_comp <- function(sal, bon) {
return(sal + bon)
}
# Apply the function across two columns at once
total_comp <- mapply(calc_total_comp, employees$salary, employees$bonus)
print(total_comp)
Just a heads-up: as you get more comfortable with these, you'll notice that sapply() is convenient but can be dangerous in production code because its return type can change depending on the input data. If you're writing a script that must be robust, stick to lapply() and explicitly convert the result to a vector yourself.
📋 Practical Task
Processing Regional Weather Station Metrics
You have been given a data frame containing weather readings from three different stations. Your goal is to process this data without using any for loops.
weather_data <- data.frame(
station = c("North", "North", "South", "South", "East", "East"),
temp_c = c(12.5, 14.2, 22.1, 25.4, 18.0, 17.5),
humidity = c(80, 85, 60, 55, 70, 72),
wind_speed = c(10, 12, 5, 8, 15, 11)
)
Your Task:
- Use
sapply()to calculate the mean of the three numeric columns (temp_c, humidity, and wind_speed). - Use
tapply()to find the averagetemp_cfor eachstation. - Create a custom function called
heat_index_simthat takestempandhumidityas arguments and returnstemp + (humidity / 10). Usemapply()to apply this function across the temperature and humidity columns to create a new vector of "Heat Index" values.
There are no comments for now.