常见的习惯用法(在书籍,教程和许多Stack Overflow问题中找到)是使用df
作为数据帧的一种丢弃标识符。我已经做了数百次似乎没有任何不良影响,但后来遇到了以下代码:
library(tree)
df <- droplevels(iris[1:100,c(1,2,5)])
tr <- tree(Species ~ ., data = df)
plot(tr)
text(tr)
partition.tree(tr)
这会出现以下错误消息:
Error in as.data.frame.default(data, optional = TRUE) :
cannot coerce class ""function"" to a data.frame
我通过反复试验发现,如果我只是将上面的df
替换为df2
,则代码会按预期工作。 是是的,df
是F分布的密度函数的名称,但这似乎与此无关。这是tree
包中的错误,还是一个重要的警示故事,其道德是我应该避免使用df
作为数据帧的名称,因为这样做会引入名称冲突?
答案 0 :(得分:2)
由于潜在的名称冲突会使错误更难以调试,因此我强迫自己长时间使用dtf
而不是df
。然而,在测试中重要的软件包收集似乎可以在测试中的任何地方使用df
,例如test-select.r:
df <- tibble(g = 1:3, x = 3:1) %>% group_by(g)
我最近一直在使用df
来命名python pandas数据帧。因此,如今我也倾向于在R中使用df
。让我们看看这是否回头。
名称空间问题不是原始问题的一部分,但与与df
的名称冲突这一问题有关。平面名称空间在探索性数据分析中更容易使用,也很有趣,您只需直接调用所有函数,但这会导致冲突。嵌套的名称空间使调试更可靠,但又麻烦一些,因为您必须在每个函数调用之前加上程序包名称。
在python中,名称空间冲突不是一个大问题,因为它具有更多的嵌套名称空间。例如,您import numpy as np
并为所有numpy函数调用加上np
,例如np.array()
。 (可以进行from numpy import *
,但是it is frowned upon和linters通常对此有所抱怨。)
在R中,必须将探索性数据分析中使用的垃圾代码与要重用的更持久的代码区分开。在第二种情况下,如果仅使用另一个包中的一个或几个函数,则最好不要导入 包,而应使用{{1}调用您真正需要的函数}。library(package_name)
答案 1 :(得分:1)
这是树包中的错误,还是一个重要的警示故事,其道德是我应该避免使用df作为数据帧的名称,因为这样做会引入名称冲突?
我认为在这种情况下它可能都是,但为了你的目的,我会把它作为一个警示的例子。它导致错误的事实表明它可能不是最好的做法。
根据我的经验,R不能很好地管理命名空间(例如,将它与Python进行比较)。因此,树的作者引入(有意或无意)与df
的冲突可能是不明智的 - 这是数据帧的常见名称 - 如果事实上他们这样做了(请参阅这里的注释)在问题中;目前还不清楚这是否是data.frame名称的冲突或eval()的不当使用导致data.frame对象和函数之间的冲突。
话虽如此,它是一个很好的例子,为什么命名空间很重要,(IMO)暗示如何编写更好的R代码。我认为名称空间被引入到R生态系统中,但我对R的经验是,有很多名称空间“平坦性”和很多名称冲突的机会。出于这个原因,我建议您将此作为为自己的变量使用更具描述性/唯一标识符的理由。这可以避免像您遇到的那样的冲突,并提供一些面向未来的证据,以帮助避免在包内部发生变化时,冲突蔓延到以前正在运行的代码中。