Присвоение нескольких значений среде
Учитывая окружающую среду 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>
В дополнение к тому, что операторы присваивания являются примитивными, нет метода S3 для [[<-
для класса environment
:
> 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 для [<-
а также [[<-
Как правильно реализовать назначение подмножеств для сред?
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
Я признаю, что это не очень эффективно, но должно работать для небольших сред.