I'm just starting to learn R and, in the tutorial I am following, the following type of syntax gets used often:
function(variable) <- value
To give a specific example:
width(myIRange) <- 3
In Python I know this would be myIRange.width = 3
which would just be setting the attribute of the myIRange
object. Since, in R, width
is just a function, how does setting the result of calling it on myIRange
actually affect myIRange
?
CodePudding user response:
We can show what's going on more clearly by writing a little function to create objects of S3 class "box", to represent a box with a specified height, width and length:
make_box <- function(height, width, length) {
structure(list(height = height, width = width, length = length),
class = "box")
}
We also want a function to be able to retrieve the width of box
objects:
width <- function(b)
{
if(class(b) != "box") stop("Can only get width of objects of class box")
return(b$width)
}
For clarity, we will also define a print method for our box
class:
print.box <- function(b) {
cat("A box of dimension", paste(b$height, b$width, b$length, sep = " x "),
"and volume", b$height * b$width * b$length)
}
So now we can create a box
:
my_box <- make_box(height = 1, width = 2, length = 3)
my_box
#> A box of dimension 1 x 2 x 3 and volume 6
And extract its width:
width(my_box)
#> [1] 2
However, if we try to assign a new width using the assignment syntax, we throw an error:
width(my_box) <- 3
#> Error in width(my_box) <- 3: could not find function "width<-"
Notice that there is no such function. We need to tell R what we mean with this syntax:
`width<-` <- function(b, value)
{
b$width <- value
return(b)
}
So now when we do:
width(my_box) <- 3
We get no error, and we can see that my_box
has had its width
member updated:
my_box
#> A box of dimension 1 x 3 x 3 and volume 9
This works because the parser knows that if we are using the "assign to a function call" syntax, then it's supposed to look for the appropriate subassignment function. It therefore effectively interprets width(my_box) <- 3
as my_box <- 'width<-'(my_box, 3)
Created on 2021-09-23 by the reprex package (v2.0.0)