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
150: Building a Survey Data Analysis Tool
By the time you get to lesson 150, you've likely realized that real-world data is rarely clean. When you're building a tool to analyze survey data—like a customer satisfaction survey for a coffee chain—you aren't just running a few mean() functions. You're fighting with inconsistent strings, missing values, and the need to turn "Strongly Agree" into a number that R can actually calculate. I've built a dozen of these tools, and the secret is spending 80% of your time on the data transformation pipeline before you even touch a plot.
How do I turn text-based Likert scales into numbers without writing a hundred if-statements?
If you have columns like "Very Dissatisfied" through "Very Satisfied," don't use a massive case_when or a series of if blocks. It's tedious and prone to typos. The professional way to do this is with a named vector. It acts like a lookup table. I usually define the scale once at the top of my script so I can change the weighting later if the client decides "Neutral" should be a 0 instead of a 3.
# Our mapping vector
likert_map <- c("Very Dissatisfied" = 1, "Dissatisfied" = 2,
"Neutral" = 3, "Satisfied" = 4, "Very Satisfied" = 5)
# Apply it across multiple columns using mutate and across
survey_data <- survey_data %>%
mutate(across(c(coffee_quality, service_speed, store_cleanliness),
~ likert_map[.x]))
The across() function is your best friend here. Instead of repeating the logic for every column, you just tell R: "Find these three columns and swap the text for the corresponding value in my map."
What's the best way to handle the "messy" open-ended comments?
Survey tools always have that one open-ended "Any other feedback?" box. You can't average a sentence, but you can flag keywords. I usually build a simple "sentiment flag" system. Rather than diving into complex Natural Language Processing (NLP) libraries immediately, start by searching for high-signal words using stringr. It's faster to implement and often just as effective for a first-pass analysis.
library(stringr)
survey_data <- survey_data %>%
mutate(complaint_flag = str_detect(comments, regex("slow|cold|rude|expensive", ignore_case = TRUE)),
praise_flag = str_detect(comments, regex("amazing|fast|friendly|love", ignore_case = TRUE)))
Now you have boolean columns. You can quickly see if there's a correlation between a low "service_speed" score and the "complaint_flag." If a customer gave a 2 but didn't mention "slow" in their comments, you know the issue was something else entirely.
How can I generate a summary table for all questions at once instead of one by one?
This is where most people get stuck. They write a separate summary block for every survey question. If your survey has 50 questions, your script becomes a nightmare. The trick is to pivot your data from "wide" to "long" format. Once the data is long, you can group by the question name and calculate everything in one shot.
library(tidyr)
summary_report <- survey_data %>%
select(customer_id, coffee_quality, service_speed, store_cleanliness) %>%
pivot_longer(cols = -customer_id, names_to = "question", values_to = "score") %>%
group_by(question) %>%
summarise(
avg_score = mean(score, na.rm = TRUE),
std_dev = sd(score, na.rm = TRUE),
response_count = n()
)
I love this approach because adding a new question to your survey doesn't require adding new code to your analysis; you just add the column name to the select() call, and the rest of the pipeline handles it automatically.
📋 Practical Task
Exercise: Building a Remote Work Satisfaction Aggregator
You have been handed a raw dataset from a company's "Remote Work Experience" survey. The data is messy and needs to be processed into a clean summary report.
The Dataset: Create a data frame called remote_survey with the following columns:
emp_id: 1 to 5work_life_balance: (Values: "Poor", "Fair", "Good", "Excellent")tech_support: (Values: "Poor", "Fair", "Good", "Excellent")feedback: (Short strings like "I love my home office", "VPN is too slow", "Management is great", "Too many meetings", "Everything is fine")
Your Task:
- Create a named vector to map the quality levels ("Poor" through "Excellent") to numbers 1 through 4.
- Use
mutate(across(...))to convert both thework_life_balanceandtech_supportcolumns to numeric values. - Create a new column called
tech_issuethat isTRUEif thefeedbackcolumn contains the word "VPN" or "slow", andFALSEotherwise. - Pivot the numeric columns into a long format and calculate the average score for each category.
There are no comments for now.