Jon*_*aus 6 environment r r-s3
给定一个环境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
Run Code Online (Sandbox Code Playgroud)
我希望使用内置的S3功能来编写一个[<-
.我注意到的第一个古怪的是,这两个[[<-
和[<-
是原始的功能,尽管模仿S3功能:
> methods("[<-")
[1] [<-.data.frame [<-.Date [<-.environment [<-.factor [<-.POSIXct [<-.POSIXlt [<-.raster* [<-.ts*
Run Code Online (Sandbox Code Playgroud)
通常,S3函数具有body只是调用的格式UseMethod
.例如:
> summary
function (object, ...)
UseMethod("summary")
<bytecode: 0x1a7c3a8>
<environment: namespace:base>
Run Code Online (Sandbox Code Playgroud)
除了赋值运算符是原始的,[[<-
对于类没有S3方法environment
:
> methods(class = environment)
[1] as.list.environment
Run Code Online (Sandbox Code Playgroud)
因此[[<-
,如果原始函数存在这样的默认值,则必须使用默认值来完成原始赋值.尽管如此,我实现了S3功能[<-.environment
:
> `[<-.environment` = function(x, names, values) {
mapply(function(name, value) { x[[name]] <- value }, names, values) }
Run Code Online (Sandbox Code Playgroud)
这看起来好像是为以下内容正确实现的:
> methods(class = environment)
[1] [<-.environment as.list.environment
> methods(`[<-`)
[1] [<-.data.frame [<-.Date [<-.environment [<-.factor [<-.POSIXct [<-.POSIXlt [<-.raster* [<-.ts*
Run Code Online (Sandbox Code Playgroud)
但是,它遇到了同样的错误:
> 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
Run Code Online (Sandbox Code Playgroud)
可能有人解释这两个与S3方法的不一致[<-
和[[<-
,以及如何正确地实施环境子集分配?
这是一个开始,修改自?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)
Run Code Online (Sandbox Code Playgroud)
给予:
$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
Run Code Online (Sandbox Code Playgroud)
我承认这效率不高,但应该适用于小型环境。