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
96: Attributes and Custom Object Classes
Think of an R object like a shipping package. The "data" is the actual item inside the box—say, a pair of shoes. But the box itself has labels stuck to the outside: the shipping address, the weight, a "Fragile" sticker, and a tracking number. These labels aren't the shoes, but they provide critical context about how to handle the shoes. If a handler sees the "Fragile" label, they treat the box differently than if it were labeled "Indestructible."
In R, these labels are called attributes. Most of the time, you use attributes without realizing it. When you create a data frame, R is actually just creating a list and slapping a "data.frame" label on the class attribute. That label is what tells R, "Hey, don't treat this like a normal list; treat it like a table."
Adding metadata to your data
You can attach your own custom attributes to almost any object using the attr() function. Let's say you're recording temperature readings. A raw number like 22.5 is useless if you don't know if it's Celsius or Fahrenheit. Instead of creating a complex list, you can just attach the unit as an attribute.
temp <- 22.5
attr(temp, "unit") <- "Celsius"
attr(temp, "location") <- "Lab A"
# To see all the labels on our "box"
attributes(temp)
I've found that using attributes is a great way to keep your data "clean" while still carrying the context you need. It keeps the actual value as a simple numeric type, so your math doesn't break, but the metadata is right there if you need to query it later.
Teaching R how to handle your custom objects
Now, here is where it gets powerful. If you set an attribute called class, you've officially created a custom object class. This is the foundation of R's S3 system. By giving an object a class, you're telling R, "Whenever a generic function is called on this object, look for a specific version of that function designed for this class."
Let's turn our temperature variable into a TempReading object. Right now, if you print it, R just shows 22.5. That's boring and potentially dangerous if you forget the units.
class(temp) <- "TempReading"
By itself, this doesn't change how the object looks. But now we can write a method specifically for the print function that targets TempReading objects.
The magic of generic functions
In R, print() is a "generic" function. When you call it, R looks at the class of the object and searches for a function named print.className. If it finds one, it uses it; otherwise, it falls back to the default.
Check this out:
print.TempReading <- function(x, ...) {
unit <- attr(x, "unit")
loc <- attr(x, "location")
cat(sprintf("Temperature: %.1f %s (Recorded at: %s)\n", x, unit, loc))
}
# Now try printing the object again
print(temp)
Suddenly, print(temp) doesn't just output a number; it outputs a formatted string. I love this pattern because it allows you to keep your data structures simple while making the representation of that data highly professional and informative. You aren't changing the value; you're just changing how R talks about it.
📋 Practical Task
Building a Currency Conversion Object
Your task is to create a custom R class that handles monetary values. A simple number isn't enough because we need to know which currency we are dealing with.
- Create a numeric variable
balancewith a value of150.75. - Assign it two attributes:
"currency"(e.g., "USD", "EUR", or "GBP") and"account_holder"(a name of your choice). - Assign the class
"Money"to this object. - Write a custom
print.Moneymethod that prints the balance formatted with the currency symbol and the account holder's name.
Example Output: "Account: Jane Doe | Balance: 150.75 USD" - Test your implementation by calling
print(balance).
There are no comments for now.