I want to write a function, labels
, that works as follows:
x <- 1:6
labels(x)
# [1] 1 2 3 4 5 6
labels(x) <- 2:7
labels(x)
# [1] 2 3 4 5 6 7
labels(x)[1:2] <- 9:10
labels(x)
# [1] 9 10 4 5 6 7
How can I do so?
What you seem to want is to understand replacement functions. If we look at names
, we also note that there is a names<-
function as well, with the following definition:
> `names<-`
function (x, value) .Primitive("names<-")
Which isn't very informative about what it actually does, but shows that you can write any function of the form foo<-
that replaces some components of the object the function is applied to.
x <- 1:6
X <- matrix(1:9, ncol = 3)
Labels <- function(obj, ...) {
UseMethod("Labels")
}
Labels.numeric <- function(obj, ...) {
names(obj)
}
Labels.matrix <- function(obj, which = c("colnames","rownames"), ...) {
if(missing(which))
which <- "colnames"
which <- match.arg(which)
if(which == "colnames") {
out <- colnames(obj)
} else {
out <- rownames(obj)
}
out
}
`Labels<-` <- function(obj, ..., value) {
UseMethod("Labels<-")
}
`Labels<-.numeric` <- function(obj, ..., value) {
names(obj) <- value
obj
}
Which can be used as follows:
> x <- 1:6
> Labels(x)
NULL
> Labels(x) <- LETTERS[1:6]
> x
A B C D E F
1 2 3 4 5 6
A matrix method, might be:
`Labels<-.matrix` <- function(obj, which = c("colnames","rownames"), ..., value) {
if(missing(which))
which <- "colnames"
which <- match.arg(which)
if(which == "colnames") {
colnames(obj) <- value
} else {
rownames(obj) <- value
}
obj
}
Which is used as:
> Labels(X)
NULL
> Labels(X) <- letters[1:3]
> X
a b c
[1,] 1 4 7
[2,] 2 5 8
[3,] 3 6 9
> Labels(X, which = "rownames") <- LETTERS[24:26]
> X
a b c
X 1 4 7
Y 2 5 8
Z 3 6 9
The trick is to remember that replacement functions are called with a value
argument that takes the values from the right hand side of <-
, so your function definition needs to have a value
argument, and use this argument to set/change the labels.
Of course, all this can be done using names
, colnames
etc, but if you want to understand how this works then hopefully the above is of use?
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With