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
152: Contributing to Open Source R Packages
Look, the jump from using a package to actually contributing to one feels like a huge leap, but it's mostly just a shift in workflow. You aren't just writing a script anymore; you're working within someone else's ecosystem. The goal isn't just to "make it work," but to make it fit.
How do I actually set up the package on my machine so I can start hacking?
You don't just download a ZIP file. You need the git history. Once you've forked the repository on GitHub, clone it locally. But here is the part that trips people up: don't just use library(package). If you do that, you're loading the version installed in your R library, not the code you're currently editing in your folder.
Instead, use devtools::load_all(). This simulates installing the package and loading it, but it points directly to your local files. I use this constantly. It’s the fastest way to iterate.
# After cloning the repo and opening the project in RStudio
devtools::load_all()
# Now you can test the function you just modified
my_package_function(x = 10)
How do I make sure my "fix" doesn't accidentally break ten other things?
In a script, you just run the code and see if it works. In a package, you use testthat. If you've found a bug, the very first thing you should do—before writing a single line of the fix—is write a test that fails. This proves the bug exists and gives you a clear goal.
If you're contributing to a package like dplyr or ggplot2, the test suites are massive. Don't try to run everything every time. Focus on the specific test file related to the function you're touching.
# Create a new test file in tests/testthat/test-my-fix.R
test_that("edge case with NA values is handled correctly", {
expect_equal(my_package_function(c(1, NA, 3)), c(1, 0, 3))
})
# Run the tests
devtools::test()
Once the test fails, write your fix. Once the test passes, you've officially moved the needle.
What makes a Pull Request that a maintainer actually wants to merge?
Maintainers are usually exhausted and overworked. The worst thing you can do is send a "mega-PR" that changes five different functions, updates the README, and tweaks the license. That's a nightmare to review.
Keep your PRs atomic. One issue, one fix, one PR. In your description, don't just say "Fixed bug." Tell them why it happened and how you fixed it. Mention the issue number (e.g., "Closes #124"). I've seen great code get rejected simply because the author didn't explain the reasoning, leaving the maintainer to guess if it was a hack or a proper architectural choice.
Wait, do I have to manually edit the .Rd files for documentation?
Please, for the love of R, don't touch the .Rd files in the man/ folder. Those are machine-generated. If you change a function's arguments or add a new one, you update the roxygen2 comments directly above the function definition in the R/ folder.
It looks like this:
#' Add two numbers together
#' @param x A numeric value
#' @param y A numeric value
#' @return The sum of x and y
#' @export
add_numbers <- function(x, y) {
x + y
}
After updating those tags, run devtools::document(). This updates the documentation files automatically. If you forget this step, the package will fail the build check, and the maintainer will have to ask you to fix it, which just adds friction to the process.
📋 Practical Task
Exercise: Implementing a Bug Fix and Test for the "rstatshelper" Package
Imagine you have cloned a utility package called rstatshelper. You discovered that the function calculate_mean_trimmed() crashes when the input vector is empty, rather than returning NA.
Your Goal: Simulate the contribution workflow by completing the following steps in your local environment (or a mock project):
- Create a Failing Test: Create a file
tests/testthat/test-mean-trimmed.R. Write atest_thatblock that passes an empty numeric vectornumeric(0)tocalculate_mean_trimmed()and expects the result to beis.na(). Run it and confirm it fails. - Implement the Fix: Locate the function in the
R/directory. Add a conditional check at the start of the function to returnNAif the length of the input vector is zero. - Verify: Run
devtools::load_all()followed bydevtools::test()to ensure the test now passes. - Update Documentation: Add a
@section Edge Cases:block to theroxygen2comments of the function, explaining that empty vectors returnNA. Rundevtools::document()to update the help files.
There are no comments for now.