Reputation: 1196
I am a fluent, long-time R user and am starting to familiarize myself with classes and methods. I am still very new to this and working through concepts.
Specifically today I am trying to apply a method to a list of objects, all of which are in a particular, user-generated class.
Take this example:
#define car
setClass("car",
representation(
name = "character",
mpg = "numeric"
)
)
#create some cars
cars <- lapply(1:nrow(mtcars), function(x) new("car", name =
rownames(mtcars)[x], mpg = mtcars$mpg[x]))
##SAMPLE MPG GROWTH METHOD
setGeneric("grow.mpg", function(car) {
standardGeneric("grow.mpg")
})
setMethod("grow.mpg",
signature("car"),
function(car){
old_mpg <- car@mpg
car@mpg <- car@mpg * .1 + car@mpg
message(paste("growing mpg on ", car@name, " from ", old_mpg, " to
", car@mpg, sep = ''))
return(car)
})
#APPLY METHOD
cars[[1]] <- grow.mpg(cars[[1]])
growing mpg on Mazda RX4 from 25.41 to 27.951
This successfully grows mpg by 10% on cars[[1]]
:
cars[[1]]
An object of class "car"
Slot "name":
[1] "Mazda RX4"
Slot "mpg":
[1] 27.951
But applying method grow.mpg
to all of cars
throws the following error:
cars <- grow.mpg(cars)
Error in (function (classes, fdef, mtable) :
unable to find an inherited method for function ‘grow.mpg’ for
signature ‘"list"’
So two questions:
grow.mpg
to all of cars
?Thanks in advance!
Upvotes: 1
Views: 731
Reputation: 206197
You've defined your grow.mpg
function for objects of class "car". And class(cars[[1]])
is a "car" but class(cars)
is "list".
Just like anything else in R (and not really unique to S4 classes), whenever you want to apply the same function to every element in the list and get a new list, back, you just use lapply
.
cars <- lapply(cars, grow.mpg)
Upvotes: 2