您是使用attach()还是通过名称或切片调用变量?

时间:2009-08-21 05:45:35

标签: r coding-style

许多介绍R书籍和指南都是从附加data.frame的做法开始的,这样您就可以按名称调用变量。我一直觉得用$符号或方括号切片[,2]来调用变量是有利的。这样我可以使用多个data.frame而不会混淆它们和/或使用迭代来连续调用感兴趣的列。我注意到谷歌最近发布了coding guidelines for R,其中包括

  

1)附上:避免使用

人们如何看待这种做法?

7 个答案:

答案 0 :(得分:25)

我从不使用附件。 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

编辑:hadley在评论中提到变换。这是一些代码:

 > 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

答案 1 :(得分:13)

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

 with(someDataFrame,  someFunction(...))

这也自然导致subset是第一个参数的形式:

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

这清楚地表明我们对选择的数据进行操作。虽然许多建模函数同时具有datasubset参数,但上面的使用更加一致,因为它也适用于那些没有datasubset参数的函数。

答案 2 :(得分:8)

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

教科书中经常使用附加的一个主要原因是缩短了代码。

答案 3 :(得分:7)

“依恋”是一种邪恶的诱惑。 唯一适用的地方是教室设置,其中一个给出一个数据帧,并希望编写代码行来对该一个数据帧进行分析。一旦完成分配并交付,用户就不可能再次使用该数据。

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

答案 4 :(得分:3)

我不想使用attach(),因为每次调用attach()时,很容易多次运行一批代码。每次都会将数据框添加到搜索路径中,从而不必要地扩展它。当然,良好的编程习惯也是在代码块结束时detach(),但这常常被遗忘。

相反,我使用xxx $ y或xxx [,“y”]。它更透明。

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

答案 5 :(得分:3)

就像Leoni所说,withwithinattach的完美替代品,但我不会完全忽视它。我有时会使用它,当我直接在R提示符下工作并希望在将它们写入脚本之前测试一些命令。特别是在测试多个命令时,attach可能是withwithin的一个更有趣,更方便,更无害的替代方法,因为在运行attach之后,命令提示符清晰为了你写输入和看输出。

完成后,请确保detach您的数据!

答案 6 :(得分:2)

虽然我也不想使用attach(),但是当你需要在程序的生命周期中保留一个对象(在这种情况下,data.frame)时,它确实有它的位置有几个功能使用它。我不认为将对象传递给使用它的每个R函数,而是将它保存在一个地方并根据需要调用它的元素更方便。

那就是说,只有当我知道有多少内存可用时才会使用它,并且只有在我超出范围时确保我detach() data.frame

我有道理吗?