Write a function that can work like 'labels (x) <- some_value`

I want to write a labels function 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 this?

+4
source share
4 answers

It looks like you need to understand the replacement functions. If we look at names , we also note that there is also a function names<- with the following definition:

 > `names<-` function (x, value) .Primitive("names<-") 

This is not 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 to which the function applies.

 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 } 

What can be used as follows:

 > x <- 1:6 > Labels(x) NULL > Labels(x) <- LETTERS[1:6] > x ABCDEF 1 2 3 4 5 6 

The matrix method can 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 } 

Used as:

 > Labels(X) NULL > Labels(X) <- letters[1:3] > X abc [1,] 1 4 7 [2,] 2 5 8 [3,] 3 6 9 > Labels(X, which = "rownames") <- LETTERS[24:26] > X abc X 1 4 7 Y 2 5 8 Z 3 6 9 

The trick is to remember that the replacement functions are called with the argument value , which takes the values โ€‹โ€‹from the right side of <- , therefore, to define your function, there must be a value argument and use this argument to set / change labels.

Of course, all this can be done using names , colnames , etc., but if you want to understand how it works, then I hope this is useful?

+6
source

If you replace โ€œlabelsโ€ with โ€œnamesโ€, this will work right now.

 x <- 1:6 names(x) names(x) <- 2:7 # and now that x "names" will be 2:7 names(x)[1:2] <- 9:10 # being able to do this is really cool x 9 10 4 5 6 7 1 2 3 4 5 6 

? names are common to many R objects: vectors, lists, data.frames and are supported for each of [and [] and can be easily applied to new classes and methods.

+2
source

here is an example:

 `f` <- function(x) { x$a } `f<-` <- function(x, value){ x$a <- value x } 

then

 > d <- data.frame(a=1:3, b=3:1) > f(d) <- 2 > print(d) ab 1 2 3 2 2 2 3 2 1 > > f(d)[3] <- 3 > print(d) ab 1 2 3 2 2 2 3 3 1 

you need to define the function f and f<- .

and although I'm not sure what you expect from the "label" function, here is the simplest replacement example:

 `labels` <- function(x) x `labels<-` <- function(x, value) x <- value 

then

 > x <- 1:6 > labels(x) [1] 1 2 3 4 5 6 > labels(x) <- 2:7 > x [1] 2 3 4 5 6 7 > labels(x)[1:2] <- 9:10 > x [1] 9 10 4 5 6 7 
+2
source

I may not understand your question very well, but I think you need a factor here that has values โ€‹โ€‹and labels (levels). For instance:.

 > x <- as.factor(1:7) > x [1] 1 2 3 4 5 6 7 Levels: 1 2 3 4 5 6 7 > levels(x) [1] "1" "2" "3" "4" "5" "6" "7" > levels(x)[1:2] <- 9:10 > x [1] 9 10 3 4 5 6 7 Levels: 9 10 3 4 5 6 7 > as.numeric(x) [1] 1 2 3 4 5 6 7 
0
source

Source: https://habr.com/ru/post/1334488/


All Articles