Daniel Hoop
Daniel Hoop

Reputation: 692

How does the assignment of colnames work "behind the scenes"?

(I hope that this question hasn't been asked before). For convenience I am using abbreviations for functions like "cn" instead of "colnames". However, for colnames/rownames the abbreviated functions only work for reading purposes. I am not able to set colnames with that new "cn" function. Can anyone explain the black magic behind the colnames function? This is the example:

cn <- match.fun(colnames)
x <- matrix(1:2)
colnames(x) <- "a" # OK, works.
cn(x) <- "b" # Error in cn(x) <- "b" : could not find function "cn<-"

Upvotes: 1

Views: 68

Answers (1)

Daniel Hoop
Daniel Hoop

Reputation: 692

Thank you, echasnovski, for the link to that great website. It has helped me a lot to better understand R! http://adv-r.had.co.nz/Functions.html#replacement-functions

In R, special "replacement functions" like foo<- can be defined. E.g. we can define a function

`setSecondElement<-` <- function(x, value){
  x[2] <- value
  return(x)
}
# Let's try it:
x <- 1:3
setSecondElement(x) <- 100
print(x)
# [1]   1 100   3

The colnames<- function works essentially the same. However, "behind the scenes" it will check if x is a data.frame or matrix and set either names(x) or dimnames(x)[[2]]. Just execute the following line in R and you'll see the underlying routine.

print( `colnames<-` )

For my specific problem the solution turns out to be very simple. Remember that I'd like to have a shorter version of colnames which shall be called cn. I can either do it like this:

cn     <- match.fun(colnames);

`cn<-` <- function(x, value){
  colnames(x) <- value
  return(x)
}

More easily, as Stéphane Laurent points out, the definition of `cn<-` can be simplified to:

`cn<-` <- `colnames<-`

There is a minor difference between these approaches. The first approach will define a new function, which calls the colnames<- function. The second approach will copy the reference from the colnames<- function and make exactly the same function call even if you use cn<-. This approach is more efficient, since 1 additinal function call will be avoided.

Upvotes: 1

Related Questions