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
60: Building Models with tidymodels
Why bother with tidymodels when I can just use a basic function like glm() or randomForest()?
I get this a lot. If you're just running one quick model, glm() is perfectly fine. But the moment you start trying different algorithms—maybe moving from a logistic regression to a random forest to a boosted tree—you'll notice that every single R package has its own weird way of handling formulas, predicting new data, and formatting results. It becomes a nightmare to maintain.
That's where parsnip (the heart of tidymodels) comes in. It creates a unified interface. You define the model type and the engine separately. If you decide to swap your engine from "glm" to "stan", you only change one line of code, and the rest of your pipeline stays exactly the same. Here is how that looks in practice:
library(tidymodels)
# Define a logistic regression model
log_spec <- logistic_reg() %>%
set_engine("glm") %>%
set_mode("classification")
# Now, if I wanted to try a Random Forest instead,
# I just change the spec, not the whole workflow:
rf_spec <- rand_forest() %>%
set_engine("ranger") %>%
set_mode("classification")
It keeps your code clean and prevents you from having to relearn the documentation for every single package on CRAN.
How do I handle data preprocessing without creating ten different versions of my dataframe?
In the old days, we'd manually create dummy variables or scale our data, and then we'd accidentally apply those changes to the test set using the training set's mean—which is a huge no-no called data leakage. I prefer using recipes. Think of a recipe as a set of instructions that you "prep" and then "bake."
Let's say we're predicting whether a customer will churn based on their tenure and monthly charges. We need to normalize the numbers and handle the categorical variables.
churn_recipe <- recipe(churn ~ tenure + monthly_charges + contract_type, data = train_data) %>%
step_dummy(contract_type) %>%
step_normalize(all_numeric_predictors())
# This doesn't actually change the data yet; it just defines the steps.
# We use 'prep' to calculate the means/SDs on the training data only.
prepared_recipe <- prep(churn_recipe)
# Then 'bake' to apply those exact calculations to any dataset.
baked_train <- bake(prepared_recipe, new_data = train_data)
baked_test <- bake(prepared_recipe, new_data = test_data)
Is there a way to bundle the recipe and the model together so I don't have to call them separately?
Yes, and this is honestly the best part of the ecosystem: workflows. A workflow is basically a container that holds your recipe and your model specification. Instead of manually baking your data and then passing it into a model, you just tell the workflow to "fit" the whole thing.
It makes your code much more readable and significantly reduces the chance of you making a mistake during the deployment phase. I almost always use workflows for anything beyond a toy project.
# Bundle everything together
churn_wf <- workflow() %>%
add_recipe(churn_recipe) %>%
add_model(log_spec)
# Fit the entire pipeline in one go
final_fit <- fit(churn_wf, data = train_data)
# Now predicting is a breeze
predictions <- predict(final_fit, new_data = test_data)
By wrapping everything in a workflow, tidymodels handles the "prep" and "bake" steps under the hood. You just feed it the raw training data, and it handles the rest.
📋 Practical Task
Build a Wine Quality Classification Workflow
Using the wine dataset (you can use read.csv("https://archive.ics.uci.edu/ml/machine-learning-databases/wine-quality/winequality-red.csv", sep=";")), build a tidymodels pipeline to predict if a wine is "high quality" (binary classification).
- Step 1: Create a binary target variable
quality_binwhere wines with a quality score of 7 or higher are "high" and others are "low". - Step 2: Define a
logistic_reg()model specification using the"glm"engine. - Step 3: Create a
recipethat normalizes all numeric predictors. - Step 4: Combine the model and recipe into a
workflow. - Step 5: Fit the workflow to the data and use
predict()to determine the quality category for the first 5 rows of the dataset.
There are no comments for now.