许多介绍R书籍和指南的开头都是附加data.frame
的做法,以便您可以通过名称调用变量。我总是发现用$
表示法或方括号切片[,2]
来调用变量是有利的。这样我就可以使用多个data.frame
而不会混淆它们和/或使用迭代来连续调用感兴趣的列。我注意到谷歌最近发布coding guidelines for R其中包括线您是否使用attach()或通过名称或切片调用变量?
1)附:避免使用它
人们如何看待这种做法?
许多介绍R书籍和指南的开头都是附加data.frame
的做法,以便您可以通过名称调用变量。我总是发现用$
表示法或方括号切片[,2]
来调用变量是有利的。这样我就可以使用多个data.frame
而不会混淆它们和/或使用迭代来连续调用感兴趣的列。我注意到谷歌最近发布coding guidelines for R其中包括线您是否使用attach()或通过名称或切片调用变量?
1)附:避免使用它
人们如何看待这种做法?
我从不使用attach。 with
和within
是你的朋友。
示例代码:
> N <- 3
> df <- data.frame(x1=rnorm(N),x2=runif(N))
> df$y <- with(df,{
x1+x2
})
> df
x1 x2 y
1 -0.8943125 0.24298534 -0.6513271
2 -0.9384312 0.01460008 -0.9238312
3 -0.7159518 0.34618060 -0.3697712
>
> df <- within(df,{
x1.sq <- x1^2
x2.sq <- x2^2
y <- x1.sq+x2.sq
x1 <- x2 <- NULL
})
> df
y x2.sq x1.sq
1 0.8588367 0.0590418774 0.7997948
2 0.8808663 0.0002131623 0.8806532
3 0.6324280 0.1198410071 0.5125870
编辑:哈德利提到评价变换。这里是一些代码:
> transform(df, xtot=x1.sq+x2.sq, y=NULL)
x2.sq x1.sq xtot
1 0.41557079 0.021393571 0.43696436
2 0.57716487 0.266325959 0.84349083
3 0.04935442 0.004226069 0.05358049
我更喜欢不使用attach()
,因为每次调用attach()
时都会多次运行一批代码,这太容易了。数据帧每次都添加到搜索路径中,不必要地扩展它。当然,良好的编程习惯也是在代码块的末尾加上detach()
,但这经常被遗忘。
取而代之,我使用xxx $ y或xxx [,“y”]。它更透明。
另一种可能性是使用许多函数中可用的数据参数,这些函数允许在数据框中引用各个变量。例如,lm(z ~ y, data=xxx)
。
有时我从各种数据框和全局变量中调用,而这个系统意味着从来没有执行过错误的计算。 – Michelle 2012-01-26 16:00:06
附件的主要问题是它可能会导致不需要的行为。假设你的工作空间中有一个名为xyz的对象。现在你附加一个名为xyz的列的数据框abc。如果你的代码引用xyz,你能保证这是对象或数据帧列的引用吗?如果你不使用attach,那么很容易。只是xyz指的是对象。 abc $ xyz指向数据框的列。
在教科书中经常使用attach的主要原因之一是它缩短了代码。
我注意到一些教科书上说:“不要这样做,附加被用来简化例子”。 – Michelle 2012-01-26 16:01:29
我更喜欢使用with
以获得上的单个命令的attach
等效:
with(someDataFrame, someFunction(...))
这也自然会导致一个形式,其中subset
是第一个参数:
with(subset(someDataFrame, someVar > someValue),
someFunction(...))
其我们很清楚地知道,我们在选择数据时进行操作。虽然许多建模函数都有data
和subset
的论点,但上面的使用更加一致,因为它也适用于那些没有data
和subset
参数的函数。
“附加”是一种邪恶的诱惑。只有在教室设置的地方才有效,其中一个被给予单个数据帧,并且预计写入代码行以对该一个数据帧进行分析。一旦分配完成并交付,用户不太可能再次使用该数据。
然而,在现实世界中的,更多的数据帧可以被添加到特定项目中的数据集合中。此外,人们经常复制和粘贴代码块以用于类似的事情。通常是从几个月前做的事情中借用,而不记得从哪里调用的细微差别。在这种情况下,人们会因先前使用“附加”而淹死。
虽然我也不喜欢使用attach()
,但是当您有几个使用它的函数时,如果需要在程序的整个生命周期中持久保存一个对象(在本例中为data.frame
),它确实占有一席之地。与其将对象传递给每个使用它的R函数,我认为将它保留在一个地方并根据需要调用它的元素会更方便。
这就是说,如果我知道我有多少内存可用,并且只有在确定我detach()
这个data.frame
一旦超出范围时,我才会使用它。
我有道理吗?
就像Leoni说的,with
和within
是attach
的完美替代品,但我不会完全否定它。我有时会使用它,当我直接在R提示符下工作,并想在将脚本写入脚本之前先测试一些命令。特别是在测试多个命令时,attach
对于with
和within
可能是一个更有趣,更方便,甚至无害的替代方案,因为在运行attach
之后,命令提示符已清除,可供您编写输入并查看输出。
完成后请确保您的数据为detach
!
'transform'是内部另一个有用的变体。 – hadley 2009-08-23 14:24:37
其实我只注意到不像'attach()','with()'不能“通过”解析函数。首先设置'printx < - function {print(x)}'。现在,即使'with(list(x = 42),print(x))'和'attach(list(x = 42)),'with(list(x = 42),printx())'失败。 printx()'成功了! :( – 2011-09-20 12:52:06