循环向量并检查是否存在具有相同名称的data.frames

mar*_*ego 3 loops r dataframe

正如标题中所描述的,我试图在包含字符串的向量上循环,这可能是或可能是data.frames的名称.它不需要是vector,实际上它是一个data.frame,我提取了一列.这是我尝试过的:

tables <- as.vector(df.stattributes.run[,1])
Run Code Online (Sandbox Code Playgroud)

这给了

tables [1]"ttest""ttest2""mtcars"

然后我开始循环

for (i in 1:length(tables))
  {try(if(!is.data.frame(as.name(tables[i])) == TRUE) stop(paste("Table",tables[i],"doesn't exist.")) else print(paste("Table",tables[i],"found")))}
Run Code Online (Sandbox Code Playgroud)

这总是会回复"表...未找到".虽然mtcars是现有的data.frame.我可以改变什么来使它工作?谢谢!

bgo*_*dst 5

您可以使用mget()with inherits=Tifnotfound=list(NULL)(或任何非data.frame值)并应用于is.data.frame()每个:

sapply(mget(tables,inherits=T,ifnotfound=list(NULL)),is.data.frame);
##  ttest ttest2 mtcars
##  FALSE  FALSE   TRUE
Run Code Online (Sandbox Code Playgroud)

inherits=T这里需要的原因是,mtcars它不存在于全局环境中,mget()当您在顶层运行时,默认情况下将在该环境中查找.它实际上驻留在内置数据集包的公共环境中.您可以使用它find()来标识对象所在的位置:

find('mtcars');
## [1] "package:datasets"
Run Code Online (Sandbox Code Playgroud)

此外,我还应该在这里解决一些误解.该as.name()功能完全等同于as.symbol().这些函数将给定参数强制转换为符号类型.

符号类型是R语言本身的R表示的一部分,或者R语言树的表示,使用R数据类型.换句话说,你可能会说它是R的R数据模型的一部分.有关方面的更多信息,请参阅我的答案.

大多数时候,大多数R程序员不需要使用符号,因为他们不需要"在语言上计算",因为它经常被调用(意味着他们不需要操纵R解析树).

在您的代码中,您将字符串值强制tables[i]转换为使用的符号类型as.name(),然后将结果符号对象传递给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
Run Code Online (Sandbox Code Playgroud)

所以我们实际上可以通过电话说你在正确的轨道上as.name().