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
30: Debugging R Code
We've all been there. You write a function that works perfectly on your test case, you deploy it to a larger dataset, and suddenly R screams at you with an error that feels like a riddle. One of the most frustrating errors for R developers is the dreaded the condition has length > 1 warning or error. It usually happens when you're trying to use a standard if statement on something that R thinks is a vector.
Take a look at this snippet. I'm trying to write a simple function to categorize the "health" of a server based on its response time in milliseconds.
categorize_latency <- function(latency) {
if (latency < 100) {
return("Healthy")
} else if (latency < 500) {
return("Warning")
} else {
return("Critical")
}
}
# This works fine
categorize_latency(50)
# But this crashes the pipeline
latencies <- c(50, 120, 600)
categorize_latency(latencies)
When you run that last line, R throws: Error in if (latency < 100) { : the condition has length > 1. If this were buried inside a 500-line script, you might spend an hour staring at the code wondering why it's failing now when it worked five minutes ago.
Tracing the crash with traceback()
When a script crashes, your first instinct might be to just restart the session and try again. Don't do that. Instead, immediately run traceback() in your console. This function prints the call stack—essentially a map of every function call that led up to the error.
In a complex project, traceback() tells you exactly which nested function failed. In our case, it would point directly to the if (latency < 100) line. The problem is that if is a scalar operator; it expects a single TRUE or FALSE. But we passed it a vector of three values. R doesn't know which one of those three you want to use to decide the branch, so it gives up.
Using browser() to pause time
If traceback() isn't enough because the logic is more subtle, I want you to start using browser(). This is my absolute favorite tool in R. By inserting browser() into your code, you tell R: "Stop everything right here and let me look around."
categorize_latency <- function(latency) {
browser() # The execution will pause here
if (latency < 100) {
return("Healthy")
}
# ... rest of code
}
When the code hits that line, your console changes. You are now "inside" the function. You can type latency to see exactly what the variable contains at that microsecond, or test latency < 100 to see that it returns TRUE FALSE TRUE instead of a single value. Once you've found the culprit, type c to continue execution or Q to quit the debugger.
Switching to vectorized logic
The fix here isn't to write a loop (which is slow in R). The fix is to use ifelse() or dplyr::case_when(). These functions are designed to handle vectors by applying the logic to every element individually.
categorize_latency_fixed <- function(latency) {
# ifelse takes (test, value_if_true, value_if_false)
# We nest them to handle multiple categories
result <- ifelse(latency < 100, "Healthy",
ifelse(latency < 500, "Warning", "Critical"))
return(result)
}
latencies <- c(50, 120, 600)
categorize_latency_fixed(latencies)
# Returns: "Healthy" "Warning" "Critical"
The reason this works is that ifelse() is vectorized. It doesn't try to make one single decision for the whole vector; it makes a decision for every single element in that vector and returns a vector of the same length. This is the "R way" of thinking—whenever you find yourself fighting with if statements in a data pipeline, you probably need a vectorized alternative.
📋 Practical Task
Fixing the Tiered Tax Calculator
You've been handed a function that calculates the tax rate for a client based on their annual income. However, the function is currently broken because it was written for single values and is now being applied to a full column of data in a dataframe.
The Broken Code:
calculate_tax_rate <- function(income) {
if (income < 30000) {
return(0.10)
} else if (income < 70000) {
return(0.20)
} else {
return(0.30)
}
}
incomes <- c(25000, 50000, 100000)
# This line causes the "condition has length > 1" error:
tax_rates <- calculate_tax_rate(incomes)
Your Goal:
- Rewrite the
calculate_tax_ratefunction so that it can accept a vector of incomes and return a vector of corresponding tax rates. - Ensure the function uses a vectorized approach (like
ifelse()) rather than aforloop. - Verify that calling
calculate_tax_rate(c(25000, 50000, 100000))returnsc(0.10, 0.20, 0.30).
There are no comments for now.