假设我们有一个x
包含列job
和的数据框income
。引用框架中的数据通常需要x$job
针对job
列中的数据和列x$income
中的数据的命令income
。
但是,使用该命令attach(x)
允许$
在引用相同数据时取消数据框的名称和符号。因此,在 R 代码中x$job
成为job
和x$income
成为。income
问题是许多 R 专家建议在 R 中attach()
编码时不要使用该命令。
主要原因是什么?应该改用什么?
何时使用它:
attach()
当我想要在大多数统计数据包(例如,Stata、SPSS)中获得的环境时,我会使用一次处理一个矩形数据集的环境 。
什么时候不使用:
然而,当你有几个不同的数据集时,它会变得非常混乱,代码很快变得不可读,特别是如果你实际上使用 R 作为一个粗略的关系数据库,其中不同的矩形数据,都与手头的问题相关,并且可能被用于匹配来自不同矩形的数据的各种方式,具有相同名称的变量。
该with()
函数或许多函数的参数是许多具有诱惑力data=
的实例的绝佳替代品。attach()
不使用的另一个原因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
我认为使用attach
. 我自己不使用它(再说一次,我喜欢动物,但也不要养动物)。当我想到 时attach
,我认为是长期的。当然,当我使用脚本时,我对它了如指掌。但是在一周、一个月或一年的时间里,当我回到脚本时,我发现搜索某个变量来自哪里的开销,太贵了。许多方法都有data
参数,这使得调用变量非常容易(sensu lm(x ~ y + z, data = mydata)
)。如果没有,我对使用with
感到满意。
简而言之,在我的书中,附加对于简短的快速数据探索来说是很好的,但对于开发我或其他人可能想要使用的脚本,我会尽量保持我的代码可读(和可转移)。
如果您执行attach(data)
多次,例如 5 次,那么您可以看到(在 的帮助下search()
)您的数据已在工作空间环境中附加了 5 次。因此,如果您将其取消附加 ( detach(data)
) 一次,环境中仍然会data
出现 4 次。因此,with()/within()
是更好的选择。它们有助于创建包含该对象的本地环境,您可以使用它而不会造成任何混淆。