Назначение нескольких значений среде одновременно

Учитывая среду x, удобным сокращением для assign(x, value, envir = e) будет запись e[[x]] <- value. В настоящее время не существует аналога оператора подмножества для присваивания сразу нескольких объектов:

> e = new.env(parent = emptyenv())
> e[["a"]] <- 1
> ls(e)
[1] "a"
> e[c("b", "c")] <- c(1,2)
Error in e[c("b", "c")] <- c(1, 2) : 
  object of type 'environment' is not subsettable

Я надеялся написать его, используя встроенную функциональность S3 для [<-. Первая странность, которую я заметил, заключалась в том, что и [[<-, и [<- являются примитивными функциями, несмотря на то, что они имитируют функции S3:

> methods("[<-")
[1] [<-.data.frame  [<-.Date        [<-.environment [<-.factor      [<-.POSIXct     [<-.POSIXlt     [<-.raster*     [<-.ts* 

Обычно функции S3 имеют формат, в котором тело представляет собой просто вызов UseMethod. Например:

> summary
function (object, ...) 
UseMethod("summary")
<bytecode: 0x1a7c3a8>
<environment: namespace:base>

В дополнение к тому, что операторы присваивания являются примитивными, для [[<- для класса environment не существует метода S3:

> methods(class = environment)
[1] as.list.environment

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

> `[<-.environment` = function(x, names, values) {
mapply(function(name, value) { x[[name]] <- value }, names, values) }

Похоже, это ведет себя так, как если бы оно было правильно реализовано для следующего:

> methods(class = environment)
[1] [<-.environment     as.list.environment
> methods(`[<-`)
[1] [<-.data.frame  [<-.Date        [<-.environment [<-.factor      [<-.POSIXct     [<-.POSIXlt     [<-.raster*     [<-.ts*  

Однако он сталкивается с той же ошибкой:

> e = new.env(parent = emptyenv())
> e[c("b", "c")] <- c(1,2)
Error in e[c("b", "c")] <- c(1, 2) : 
  object of type 'environment' is not subsettable

Может ли кто-нибудь объяснить несоответствие методов S3 для [<- и [[<-, а также как правильно реализовать назначение подмножества для сред?


person Jon Claus    schedule 13.05.2014    source источник
comment
list2env может быть здесь полезным.   -  person Tyler Rinker    schedule 14.05.2014
comment
Также это работает, но может быть не лучшим подходом: lapply(1:2, function(i) assign(c("b", "c")[i], c(1,2)[i], envir=e))   -  person Tyler Rinker    schedule 14.05.2014
comment
Сопутствующий интерес: r.789695.n4.nabble.com/ list-assignment-syntax-td4520641.html от 2012 года, был еще один от 08 года в том же духе и еще один еще раньше ('04) в качестве попытки реализации... Вы на два года раньше по запросу.   -  person Thell    schedule 14.05.2014
comment
Моя главная забота заключалась в том, как перезаписать оператор присваивания подмножества [<-, а не тело этой функции. Мой вторичный интерес заключался в том, как этот оператор и [[<- на самом деле выполняются в серверной части, поскольку они, кажется, используют функциональность S3 на поверхности, но на самом деле являются примитивными функциями.   -  person Jon Claus    schedule 15.05.2014


Ответы (1)


Вот начало, измененное с ?list2env

L <- list(a = 1, b = 2:4, p = pi, ff = gl(3, 4, labels = LETTERS[1:3]))
e <- list2env(L)
addToEnv <- function(e, names, values) {
    l1 <- sapply(values, list)
    names(l1) <- names
    el1 <- mget(ls(e), envir=e)
    al1 <- as.list(c(el1, l1))
    return(list2env(al1))
    }
e2 <- addToEnv(e, names=letters[7:8], values=letters[9:10])
mget(ls(e2), envir=e2)

давая:

$a
[1] 1

$b
[1] 2 3 4

$ff
 [1] A A A A B B B B C C C C
Levels: A B C

$g
[1] "i"

$h
[1] "j"

$p
[1] 3.141593

Я признаю, что это не очень эффективно, но должно работать для небольших сред.

person dardisco    schedule 14.05.2014