Home > OS >  How are values assigned to the result of a function call?
How are values assigned to the result of a function call?

Time:09-23

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)

  •  Tags:  
  • r
  • Related