假设我们有一个数据框x
,其中包含job
和income
列。引用框架中的数据通常需要x$job
列中的数据job
和x$income
列中的数据income
。
但是,使用命令attach(x)
允许在引用相同数据时取消数据框的名称和$
符号。因此,x$job
变为job
,x$income
在R代码中变为income
。
问题是R中的许多专家建议在R中编码时不要使用attach()
命令。
主要原因是什么?应该使用什么?
答案 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
即使分配了cars
和dist
,也未对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
中引用的speed
和time
是原始(未转换)值;当附加cars$dist
时cars$speed
和cars
的值。
答案 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()
是更好的选择。它们有助于创建包含该对象的本地环境,您可以使用它而不会产生任何混淆。