我想写一个函数labels,它的工作原理如下:
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
Run Code Online (Sandbox Code Playgroud)
我怎么能这样做?
您似乎想要的是了解替换功能.如果我们看一下names,我们也注意到有一个names<-函数,具有以下定义:
> `names<-`
function (x, value) .Primitive("names<-")
Run Code Online (Sandbox Code Playgroud)
这对于它实际上做了什么没有太多的信息,但表明你可以编写表单的任何函数foo<-来替换函数所应用的对象的某些组件.
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
}
Run Code Online (Sandbox Code Playgroud)
可以使用如下:
> x <- 1:6
> Labels(x)
NULL
> Labels(x) <- LETTERS[1:6]
> x
A B C D E F
1 2 3 4 5 6
Run Code Online (Sandbox Code Playgroud)
矩阵方法可能是:
`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
}
Run Code Online (Sandbox Code Playgroud)
用作:
> 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
Run Code Online (Sandbox Code Playgroud)
诀窍是要记住,使用value从右侧获取值的参数调用替换函数<-,因此函数定义需要有一个value参数,并使用此参数来设置/更改标签.
当然,这一切都可以做到用names,colnames等等,但如果你想了解如何希望上述工程则是使用的?