在工作区中将(几乎)所有对象存储在列表中

8
假设我的工作空间(全局环境)中有许多对象,我想将其中大部分存储在列表中。以下是一个简化的例子:
# Put some objects in the workspace
A <- 1
B <- 2
C <- 3

我可以将A和C对象存储在列表中。当然,我可以明确地这样做:
mylist <- list(A,C)

然而,当工作区中的对象数量非常大时,这将变得相当麻烦。因此,我希望以不同的方式处理,并尝试以下方法:
mylist <- list(setdiff(ls(),B))

但这显然不是我想要的,因为它只存储工作区中对象的名称。
你有什么建议吗?
非常感谢!
3个回答

14

另一个选项是使用mget

mget(setdiff(ls(),"B"))

1
不知道有mget这个命令。这样会简单得多! - juba

2
编辑:我认为在这里使用lapply/sapply会带来太多的问题。你应该毫不犹豫地使用mget答案。
你可以尝试:
mylist <- sapply(setdiff(ls(),"B"), get)

在某些情况下,即如果您的工作区中的所有对象都是相同类型的,则sapply将返回一个向量。例如:
sapply(setdiff(ls(),"B"), get)
# A C 
# 1 3 

否则,它将返回一个列表:
v <- list(1:2)
sapply(setdiff(ls(),"B"), get)
# $A
# [1] 1
# 
# $C
# [1] 3
# 
# $v
# [1] 1 2

因此,在这里使用lapply而不是sapply可能更安全,正如Josh O'Brien所指出的那样。

应该使用lapply()来避免(潜在的)将列表转换为向量。 - Josh O'Brien
3
我认为你的意思是使用 mget,并且这里用到了 "B"。换言之,可以使用 mget( setdiff( ls() , "B" ) )。+1 - Simon O'Hanlon
1
@SimonO101 当然是"B"而不是B。我只是复制/粘贴了问题中的代码,感谢你发现了它。 - juba
@SimonO101 仅供我理解,为什么输入“B”时它返回一个列表,而输入B时返回一个数字向量? - Rob
2
@Rob 因为你使用了sapply。此外,setdiff将返回所有内容(对象B未被排除,因为您正在比较对象名称的字符值与B中保存的值2)。因此,它会返回一个列表中的3个对象,所有对象的长度和类型相同,因此它会自动转换为数字向量。 - Simon O'Hanlon
@Rob 试试这个,你就知道我的意思了... B <- "A"; setdiff(ls(),B) 现在对象 A 被排除了。 - Simon O'Hanlon

2

mget在这种情况下肯定是最容易使用的。但是,您也可以使用as.list.environmenteapply来实现相同的功能:

e2l <- as.list(.GlobalEnv)
# or: e2l <- as.list(environment()) 
# using environment() within a function returns the function's env rather than .GlobalEnv
e2l[! names(e2l) %in "B"]

# the following one sounds particularly manly with `force`
e2l <- eapply(environment(), force)
e2l[! names(e2l) %in "B"]

还有一行代码:

 (function(x) x[!names(x)%in%"B"])(eapply(environment(), force))
 (function(x) x[!names(x)%in%"B"])(as.list(environment()))

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接