1
votes

While discussing S4 prototypes, Hadley states that

An empty value for age is probably not what you want

Instead, he sets a default value to NA. Here is the code

setClass("Person", representation(name = "character", age = "numeric"))

To access slots of an S4 object you use @, not $:

hadley <- new("Person", name = "Hadley")
hadley@age
# numeric(0)

An empty value for age is probably not what you want, so you can also assign a default prototype for the class:

setClass("Person", representation(name = "character", age = "numeric"), 
  prototype(name = NA_character_, age = NA_real_))
hadley <- new("Person", name = "Hadley")
hadley@age
# [1] NA

What are the advantages of setting a NA prototype instead of leaving it empty?

Doesn't it only affect the way you check for whether the slot has a non default value? i.e. length(hadley@age) == 0 vs is.na(hadley@age)?

1
One reason that I could think of is that computations with NAs give NA by default. Assume that you add the following code using your first definition of Person: Alex<-new("Person", name = "Alex",age=99); mean(unlist(lapply(list(hadley,Alex),function(person) person@age)));. It could be that you incorrectly infer that the average age in your sample is 99, whereas you do not know Hadley's age...cryo111
That is a very good reason!Alex
Can you post it as an answer please?Alex

1 Answers

1
votes

One reason that I could think of is that computations with NAs give NA by default. Assume that you add the following code using your first definition of Person

#your first definition of Person
setClass("Person", representation(name = "character", age = "numeric"))
hadley <- new("Person", name = "Hadley")
#new Person
Alex<-new("Person", name = "Alex",age=99)
#calculate mean age of two Persons
mean(unlist(lapply(list(hadley,Alex),function(person) person@age)))
#99

It could be that you incorrectly infer that the average age in your sample is 99, whereas you do not know Hadley's age.

For the second definition of Person you would get NA

setClass("Person", representation(name = "character", age = "numeric"), 
  prototype(name = NA_character_, age = NA_real_))
hadley <- new("Person", name = "Hadley")
Alex<-new("Person", name = "Alex",age=99)
mean(unlist(lapply(list(hadley,Alex),function(person) person@age)))
#NA