2009-08-21 57 views
26

许多介绍R书籍和指南的开头都是附加data.frame的做法,以便您可以通过名称调用变量。我总是发现用$表示法或方括号切片[,2]来调用变量是有利的。这样我就可以使用多个data.frame而不会混淆它们和/或使用迭代来连续调用感兴趣的列。我注意到谷歌最近发布coding guidelines for R其中包括线您是否使用attach()或通过名称或切片调用变量?

1)附:避免使用它

人们如何看待这种做法?

回答

25

我从不使用attach。 withwithin是你的朋友。

示例代码:

> 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 
+3

'transform'是内部另一个有用的变体。 – hadley 2009-08-23 14:24:37

+1

其实我只注意到不像'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

3

我更喜欢不使用attach(),因为每次调用attach()时都会多次运行一批代码,这太容易了。数据帧每次都添加到搜索路径中,不必要地扩展它。当然,良好的编程习惯也是在代码块的末尾加上detach(),但这经常被遗忘。

取而代之,我使用xxx $ y或xxx [,“y”]。它更透明。

另一种可能性是使用许多函数中可用的数据参数,这些函数允许在数据框中引用各个变量。例如,lm(z ~ y, data=xxx)

+0

有时我从各种数据框和全局变量中调用,而这个系统意味着从来没有执行过错误的计算。 – Michelle 2012-01-26 16:00:06

8

附件的主要问题是它可能会导致不需要的行为。假设你的工作空间中有一个名为xyz的对象。现在你附加一个名为xyz的列的数据框abc。如果你的代码引用xyz,你能保证这是对象或数据帧列的引用吗?如果你不使用attach,那么很容易。只是xyz指的是对象。 abc $ xyz指向数据框的列。

在教科书中经常使用attach的主要原因之一是它缩短了代码。

+0

我注意到一些教科书上说:“不要这样做,附加被用来简化例子”。 – Michelle 2012-01-26 16:01:29

13

我更喜欢使用with以获得上的单个命令的attach等效:

with(someDataFrame, someFunction(...)) 

这也自然会导致一个形式,其中subset是第一个参数:

with(subset(someDataFrame, someVar > someValue), 
     someFunction(...)) 

其我们很清楚地知道,我们在选择数据时进行操作。虽然许多建模函数都有datasubset的论点,但上面的使用更加一致,因为它也适用于那些没有datasubset参数的函数。

7

“附加”是一种邪恶的诱惑。只有在教室设置的地方才有效,其中一个被给予单个数据帧,并且预计写入代码行以对该一个数据帧进行分析。一旦分配完成并交付,用户不太可能再次使用该数据。

然而,在现实世界中的,更多的数据帧可以被添加到特定项目中的数据集合中。此外,人们经常复制和粘贴代码块以用于类似的事情。通常是从几个月前做的事情中借用,而不记得从哪里调用的细微差别。在这种情况下,人们会因先前使用“附加”而淹死。

2

虽然我也不喜欢使用attach(),但是当您有几个使用它的函数时,如果需要在程序的整个生命周期中持久保存一个对象(在本例中为data.frame),它确实占有一席之地。与其将对象传递给每个使用它的R函数,我认为将它保留在一个地方并根据需要调用它的元素会更方便。

这就是说,如果我知道我有多少内存可用,并且只有在确定我detach()这个data.frame一旦超出范围时,我才会使用它。

我有道理吗?

3

就像Leoni说的,withwithinattach的完美替代品,但我不会完全否定它。我有时会使用它,当我直接在R提示符下工作,并想在将脚本写入脚本之前先测试一些命令。特别是在测试多个命令时,attach对于withwithin可能是一个更有趣,更方便,甚至无害的替代方案,因为在运行attach之后,命令提示符已清除,可供您编写输入并查看输出。

完成后请确保您的数据为detach

相关问题