为什么不建议在R中使用attach(),我应该使用什么呢?

时间:2012-04-08 04:10:03

标签: r dataframe r-faq

假设我们有一个数据框x,其中包含jobincome列。引用框架中的数据通常需要x$job列中的数据jobx$income列中的数据income

但是,使用命令attach(x)允许在引用相同数据时取消数据框的名称和$符号。因此,x$job变为jobx$income在R代码中变为income

问题是R中的许多专家建议在R中编码时不要使用attach()命令。

主要原因是什么?应该使用什么?

4 个答案:

答案 0 :(得分:39)

何时使用:

当我希望您在大多数统计数据包(例如Stata,SPSS)中获得的环境一次使用一个矩形数据集时,我使用attach()

何时不使用

然而,当你有几个不同的数据集时,它变得非常混乱并且代码很快变得不可读,特别是如果你实际上使用R作为粗略的关系数据库,其中不同的数据矩形,都与手头的问题有关,也许以不同方式匹配来自不同矩形的数据,具有相同名称的变量。

许多函数的with()函数或data=参数是许多attach()诱人的实例的绝佳替代品。

答案 1 :(得分:22)

不使用attach的另一个原因:它允许访问数据框的列的值,仅用于读取(访问),并且在连接时也是如此。它不是该列当前值的简写。两个例子:

> head(cars)
  speed dist
1     4    2
2     4   10
3     7    4
4     7   22
5     8   16
6     9   10
> attach(cars)
> # convert stopping distance to meters
> dist <- 0.3048 * dist
> # convert speed to meters per second
> speed <- 0.44707 * speed
> # compute a meaningless time
> time <- dist / speed
> # check our work
> head(cars)
  speed dist
1     4    2
2     4   10
3     7    4
4     7   22
5     8   16
6     9   10

即使分配了carsdist,也未对speed数据集进行任何更改。

如果明确指派回数据集......

> head(cars)
  speed dist
1     4    2
2     4   10
3     7    4
4     7   22
5     8   16
6     9   10
> attach(cars)
> # convert stopping distance to meters
> cars$dist <- 0.3048 * dist
> # convert speed to meters per second
> cars$speed <- 0.44707 * speed
> # compute a meaningless time
> cars$time <- dist / speed
> # compute meaningless time being explicit about using values in cars
> cars$time2 <- cars$dist / cars$speed
> # check our work
> head(cars)
    speed   dist      time     time2
1 1.78828 0.6096 0.5000000 0.3408862
2 1.78828 3.0480 2.5000000 1.7044311
3 3.12949 1.2192 0.5714286 0.3895842
4 3.12949 6.7056 3.1428571 2.1427133
5 3.57656 4.8768 2.0000000 1.3635449
6 4.02363 3.0480 1.1111111 0.7575249

计算dist中引用的speedtime是原始(未转换)值;当附加cars$distcars$speedcars的值。

答案 2 :(得分:13)

我认为使用attach并没有错。我自己不使用它(然后再说,我喜欢动物,但也不要保留任何动物)。当我想到attach时,我认为是长期的。当然,当我使用脚本时,我内心深处都知道它。但是在一个星期的时间里,一个月或一年,当我回到脚本时,我发现搜索特定变量所在的开销,太贵了。很多方法都有data参数,这使得调用变量非常简单(sensu lm(x ~ y + z, data = mydata))。如果没有,我发现with的使用令我满意。

简而言之,在我的书中,附加可以用于简短的快速数据探索,但是对于开发我或其他人可能想要使用的脚本,我尽量保持我的代码可读(并且可转移)。

答案 3 :(得分:9)

如果您多次执行attach(data)次,例如5次,那么您可以在工作区环境中看到(在search()的帮助下)您的数据已连接5次。因此,如果您取消(detach(data))一次,那么在环境中仍然会data出现4次。因此,with()/within()是更好的选择。它们有助于创建包含该对象的本地环境,您可以使用它而不会产生任何混淆。