Напишите функцию, которая может работать как `tags (x) <- some_value` - PullRequest
4 голосов
/ 06 января 2011

Я хочу написать функцию 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

Как я могу это сделать?

Ответы [ 4 ]

6 голосов
/ 06 января 2011

То, что вы, кажется, хотите, это понять замена функций.Если мы посмотрим на names, мы также заметим, что есть также функция names<- со следующим определением:

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

, которая не очень информативна о том, что она на самом деле делает, но показываетчто вы можете написать любую функцию вида 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
}

, который можно использовать следующим образом:

> x <- 1:6
> Labels(x)
NULL
> Labels(x) <- LETTERS[1:6]
> x
A B C D E F 
1 2 3 4 5 6

Матричный метод может быть следующим:

`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
}

. Используется как:

> 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
* 1020.с правой стороны <-, поэтому в определении вашей функции должен быть аргумент value, и используйте этот аргумент для установки / изменения меток.

Конечно, все это можно сделать с помощью names, colnames и т. Д., Но если вы хотите понять, как это работает, то надеюсь, что вышеперечисленное пригодится?

2 голосов
/ 06 января 2011

вот пример:

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

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

тогда

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

вам нужно определить функции f и f<-.

и хотя я не уверен, что вы ожидаете, чтобы «пометить» функцию, вот самый простой пример замены:

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

тогда

> 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 голосов
/ 06 января 2011

Если вы замените «метки» на «имена», это сработает прямо сейчас.

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 является общим для многих объектов R: векторов, списков, data.frames и поддерживается для каждого из них [и [[, и может быть легко применен к новым классам и методам.

0 голосов
/ 06 января 2011

Возможно, я не совсем понимаю ваш вопрос, но я думаю, что вам нужен здесь фактор, который имеет значения и метки (уровни).Например:

> 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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...