📖 Scenario: You are working with R and want to understand how the S3 object system works. You will create a simple S3 class, add a method, and then use it to see how R decides which function to run based on the object class.
🎯 Goal: Build a simple S3 class called person with a print method that shows a custom message when printing the object.
📋 What You'll Learn
Create a list object with specific named elements
Assign a class attribute to the object
Write a print method for the S3 class
Call the print method by printing the object
💡 Why This Matters
🌍 Real World
S3 objects are used in many R packages to represent data with custom behaviors, such as data frames, time series, and model results.
💼 Career
Understanding S3 helps you extend R packages, write your own classes, and customize how data is displayed and processed in data science and statistical programming jobs.
Progress0 / 4 steps
1
Create a list object with class 'person'
Create a list called person1 with elements name set to "Alice" and age set to 30. Then assign the class person to person1 using class(person1) <- "person".
R Programming
Hint
Use list() to create the object and class() to assign the class.
2
Write a print method for class 'person'
Write a function called print.person that takes one argument x and prints the message "Person: " followed by the person's name and age in parentheses. Use cat() to print the message.
R Programming
Hint
Define print.person as a function with argument x. Use cat() to print the formatted string.
3
Call the print method by printing the object
Use the print() function to print the object person1. This should call your custom print.person method.
R Programming
Hint
Simply call print(person1) to trigger the S3 print method.
4
Display the output of printing the S3 object
Run the code to display the output of printing person1. The output should be exactly Person: Alice (30 years old).
R Programming
Hint
Check the console output matches exactly the expected message.
Practice
(1/5)
1. What is the main purpose of the S3 object system in R?
easy
A. To speed up the execution of R code
B. To provide a graphical user interface for R
C. To allow functions to behave differently based on the class of their input
D. To manage memory allocation automatically
Solution
Step 1: Understand S3 system role
S3 is designed to let functions act differently depending on the class of the object they receive.
Step 2: Compare options
Only To allow functions to behave differently based on the class of their input describes this behavior. Other options describe unrelated features.
Final Answer:
To allow functions to behave differently based on the class of their input -> Option C
Quick Check:
S3 purpose = different behavior by class [OK]
Hint: Remember: S3 dispatches methods by object class [OK]
Common Mistakes:
Confusing S3 with speed optimization
Thinking S3 manages memory
Assuming S3 provides a GUI
2. Which of the following is the correct way to define an S3 method for the generic function print for objects of class myclass?
easy
A. print_myclass <- function(x) { cat("My class object") }
B. print.myclass <- function(x) { cat("My class object") }
C. print(myclass) <- function(x) { cat("My class object") }
D. function print.myclass(x) { cat("My class object") }
Solution
Step 1: Recall S3 method naming convention
S3 methods are named as generic.class, here print.myclass.
Step 2: Check syntax correctness
print.myclass <- function(x) { cat("My class object") } uses correct assignment and function syntax. Others have invalid syntax or wrong naming.
Final Answer:
print.myclass <- function(x) { cat("My class object") } -> Option B
Quick Check:
S3 method = generic.class naming [OK]
Hint: Use generic.class naming to define S3 methods [OK]
Common Mistakes:
Using underscores instead of dots in method names
Incorrect function assignment syntax
Trying to assign function to generic(class)
3. What will be the output of the following R code?
obj <- structure(list(a = 1), class = "myclass")
print.myclass <- function(x) { cat("Class is myclass\n") }
print(obj)
medium
A. Class is myclass
B. [1] 1
C. Error: could not find function "print.myclass"
D. NULL
Solution
Step 1: Understand object class and method
The object has class "myclass" and a print.myclass method is defined.
Step 2: Method dispatch on print()
Calling print(obj) triggers print.myclass, which prints "Class is myclass" with a newline.
Final Answer:
Class is myclass -> Option A
Quick Check:
print dispatches to print.myclass [OK]
Hint: print calls method matching object's class [OK]
A. Error because print() does not dispatch to print.myclass
B. Error because print.myclass is not defined correctly
C. Error because class assignment is invalid
D. No error; it prints 'Value: 10'
Solution
Step 1: Check class assignment
Assigning class "myclass" to obj is valid.
Step 2: Check method definition and dispatch
print.myclass is correctly defined and print(obj) calls it, printing "Value: 10".
Final Answer:
No error; it prints 'Value: 10' -> Option D
Quick Check:
Class and method correctly set, print dispatches [OK]
Hint: Assign class before calling generic function [OK]
Common Mistakes:
Defining method after calling print
Not assigning class attribute
Misnaming method function
5. You want to create an S3 generic function describe that behaves differently for numeric and character vectors. Which of the following code snippets correctly sets up the generic and methods?
hard
A. describe <- function(x) UseMethod("describe")
describe.numeric <- function(x) { paste("Numeric with length", length(x)) }
describe.character <- function(x) { paste("Character with length", length(x)) }
B. describe <- function(x) { if (is.numeric(x)) "numeric" else "character" }
describe.numeric <- function(x) {}
describe.character <- function(x) {}