您可以将mget() 与inherits=T 和ifnotfound=list(NULL)(或任何非data.frame 值)一起使用,并将is.data.frame() 应用于每个:
sapply(mget(tables,inherits=T,ifnotfound=list(NULL)),is.data.frame);
## ttest ttest2 mtcars
## FALSE FALSE TRUE
这里之所以需要inherits=T,是因为mtcars 并不驻留在全局环境中,而当您在顶层运行mget() 时,默认情况下会出现在全局环境中。它实际上驻留在内置数据集包的公共环境中。您可以使用find() 来识别对象所在的位置:
find('mtcars');
## [1] "package:datasets"
另外,我应该在这里解决一些误解。 as.name() 函数完全等同于 as.symbol()。这些函数将给定的参数强制转换为符号类型。
符号类型是 R 对 R 语言本身的表示的一部分,或者换句话说,是 R 解析树的一部分,使用 R 数据类型。换句话说,您可能会说它是 R 的 R 数据模型的一部分。有关更多信息,请参阅我的回答 here。
大多数时候,大多数 R 程序员不需要使用符号,因为他们不需要像通常所说的那样“在语言上进行计算”(这意味着他们不需要操作 R 解析树) .
在您的代码中,您使用as.name() 将tables[i] 中的字符串值强制转换为符号类型,然后将生成的符号对象传递给is.data.frame()。这是不正确的。在符号对象上调用 is.data.frame() 将始终返回 false,因为符号不是 data.frame。一般来说,is.* 函数作用于给定对象的类型;他们不进行任何类型的“解析”或“查找”或“搜索”来找到参数所指的最终对象;参数是is.*函数进行类型测试的对象。
第二点,你不需要== TRUE。如果您已经有一个逻辑值,那么它已经为真,在这种情况下,比较会将其保留为真,或者它已经为假,在这种情况下,比较会将其保留为假(或者它已经是 NA , 在这种情况下,比较会将其保留为 NA)。
有趣的是,在写完上面的解释之后,我意识到还有另一种方法可以获取名称存储在字符串值中的对象,它实际上确实涉及到我有点不屑一顾的as.symbol()/as.name() 函数更多。我说的是在符号对象上调用eval():
head(eval(as.symbol(tables[3L])));
## mpg cyl disp hp drat wt qsec vs am gear carb
## Mazda RX4 21.0 6 160 110 3.90 2.620 16.46 0 1 4 4
## Mazda RX4 Wag 21.0 6 160 110 3.90 2.875 17.02 0 1 4 4
## Datsun 710 22.8 4 108 93 3.85 2.320 18.61 1 1 4 1
## Hornet 4 Drive 21.4 6 258 110 3.08 3.215 19.44 1 0 3 1
## Hornet Sportabout 18.7 8 360 175 3.15 3.440 17.02 0 0 3 2
## Valiant 18.1 6 225 105 2.76 3.460 20.22 1 0 3 1
is.data.frame(eval(as.symbol(tables[3L])));
## [1] TRUE
所以我们实际上可以通过调用as.name() 来说明您走在正确的轨道上。