如何通过 r 中的变量名称对环境进行子集化
How to subset an environment by its variable names in r
我想通过变量名称对环境进行子集化。
e <- new.env(parent=emptyenv())
e$a <- 1
e$b <- 2
e$d <- 3
e[ls(e) %in% c("a","b", "c")]
### if e was a list, this would return the subset list(a=1, b=2)
我不知道如何通过名称对环境元素进行子集化。使用 lapply 或 eapply 也不起作用。通过变量名称对环境进行子集化的正确或简单方法是什么?
谢谢你。
我原来的解决办法是用get()
/ mget()
(可能之前OP看到我删评论了)。然后我注意到 OP 已经尝试 eapply()
,所以我考虑了可能的解决方案。在这里(在@thelatemail 的帮助下)。
# try some different data type
e <- new.env(parent=emptyenv())
e$a <- 1:3
e$b <- matrix(1:4, 2)
e$c <- data.frame(x=letters[1:2],y=LETTERS[1:2])
您可以使用以下任一方法将环境 e
中的对象收集到列表中:
elst <- eapply(e, "[") ## my idea
elst <- eapply(e, identity) ## thanks to @thelatemail
elst <- as.list.environment(e) ## thanks to @thelatemail
#$a
#[1] 1 2 3
#$b
# [,1] [,2]
#[1,] 1 3
#[2,] 2 4
#$c
# x y
#1 a A
#2 b B
as.list.environment()
可以看作是list2env()
的逆运算。它在 ?list2env
的 "See Also" 部分中提到。
结果elst
只是一个普通列表。有多种方法可以对该列表进行子集化。例如:
elst[names(elst) %in% c("a","b")] ## no need to use "ls(e)" now
#$a
#[1] 1 2 3
#$b
# [,1] [,2]
#[1,] 1 3
#[2,] 2 4
好吧,再想一想,我建议:
mget(c("a","b"), envir=e)
#$a
#[1] 1
#
#$b
#[1] 2
mget(ls(e)[ls(e) %in% c('a','b','d')], e)
[
运算符通常 returns 与原始对象类型相同的对象,所以我猜您期待的是一个环境,而不是一个列表。相同的环境但具有不同的元素集,还是具有指定元素的新环境?无论哪种方式,我认为你最终都会迭代,例如
f = new.env(parent=emptyenv())
for (elt in c("a", "b"))
f[[elt]] = e[[elt]]
使用环境不是非常惯用的 R 代码,这可以解释为什么没有更优雅的解决方案。
您可以使用 rlang::env_get_list() 获取绑定列表:
rlang::env_get_list(env=e, c("a","b"))
#$a
#[1] 1
#
#$b
#[1] 2
如果您尝试获取一个环境而不是一个列表,除了使用 rlang::env_get_list() 的输出创建一个新环境之外,我不确定您将如何做到这一点。
如果您想在列表中包含环境中可能不存在的元素(如“c”),则必须指定默认值 - 否则会出现错误:
env_get_list(env = e, c("a","b","c"))
#Error in env_get_list(env = e, c("a", "b", "c")) : argument "default" is missing, with no default
env_get_list(env = e, c("a","b","c"),default=NULL)
#$a
#[1] 1
#
#$b
#[1] 2
#
#$c
#NULL
我假设你根本不需要 c,所以我会做类似的事情:
temp <- c("a","b","c")[c("a","b","c") %in% env_names(e)]
temp
[1] "a" "b"
env_get_list(env=e,temp)
#$a
#[1] 1
#
#$b
#[1] 2
我想通过变量名称对环境进行子集化。
e <- new.env(parent=emptyenv())
e$a <- 1
e$b <- 2
e$d <- 3
e[ls(e) %in% c("a","b", "c")]
### if e was a list, this would return the subset list(a=1, b=2)
我不知道如何通过名称对环境元素进行子集化。使用 lapply 或 eapply 也不起作用。通过变量名称对环境进行子集化的正确或简单方法是什么? 谢谢你。
我原来的解决办法是用get()
/ mget()
(可能之前OP看到我删评论了)。然后我注意到 OP 已经尝试 eapply()
,所以我考虑了可能的解决方案。在这里(在@thelatemail 的帮助下)。
# try some different data type
e <- new.env(parent=emptyenv())
e$a <- 1:3
e$b <- matrix(1:4, 2)
e$c <- data.frame(x=letters[1:2],y=LETTERS[1:2])
您可以使用以下任一方法将环境 e
中的对象收集到列表中:
elst <- eapply(e, "[") ## my idea
elst <- eapply(e, identity) ## thanks to @thelatemail
elst <- as.list.environment(e) ## thanks to @thelatemail
#$a
#[1] 1 2 3
#$b
# [,1] [,2]
#[1,] 1 3
#[2,] 2 4
#$c
# x y
#1 a A
#2 b B
as.list.environment()
可以看作是list2env()
的逆运算。它在 ?list2env
的 "See Also" 部分中提到。
结果elst
只是一个普通列表。有多种方法可以对该列表进行子集化。例如:
elst[names(elst) %in% c("a","b")] ## no need to use "ls(e)" now
#$a
#[1] 1 2 3
#$b
# [,1] [,2]
#[1,] 1 3
#[2,] 2 4
好吧,再想一想,我建议:
mget(c("a","b"), envir=e)
#$a
#[1] 1
#
#$b
#[1] 2
mget(ls(e)[ls(e) %in% c('a','b','d')], e)
[
运算符通常 returns 与原始对象类型相同的对象,所以我猜您期待的是一个环境,而不是一个列表。相同的环境但具有不同的元素集,还是具有指定元素的新环境?无论哪种方式,我认为你最终都会迭代,例如
f = new.env(parent=emptyenv())
for (elt in c("a", "b"))
f[[elt]] = e[[elt]]
使用环境不是非常惯用的 R 代码,这可以解释为什么没有更优雅的解决方案。
您可以使用 rlang::env_get_list() 获取绑定列表:
rlang::env_get_list(env=e, c("a","b"))
#$a
#[1] 1
#
#$b
#[1] 2
如果您尝试获取一个环境而不是一个列表,除了使用 rlang::env_get_list() 的输出创建一个新环境之外,我不确定您将如何做到这一点。
如果您想在列表中包含环境中可能不存在的元素(如“c”),则必须指定默认值 - 否则会出现错误:
env_get_list(env = e, c("a","b","c"))
#Error in env_get_list(env = e, c("a", "b", "c")) : argument "default" is missing, with no default
env_get_list(env = e, c("a","b","c"),default=NULL)
#$a
#[1] 1
#
#$b
#[1] 2
#
#$c
#NULL
我假设你根本不需要 c,所以我会做类似的事情:
temp <- c("a","b","c")[c("a","b","c") %in% env_names(e)]
temp
[1] "a" "b"
env_get_list(env=e,temp)
#$a
#[1] 1
#
#$b
#[1] 2