代码之家  ›  专栏  ›  技术社区  ›  John Coleman

使用“df”作为数据帧的名称安全吗?

r
  •  13
  • John Coleman  · 技术社区  · 7 年前

    一个常见的习惯用法(见于书籍、教程和许多堆栈溢出问题中)是 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公司 作为数据帧的名称,因为这样做会导致名称冲突?

    2 回复  |  直到 7 年前
        1
  •  2
  •   bjarchi    7 年前

    这是树包中的一个bug,还是一个重要的警示故事,其寓意是我应该避免使用df作为数据帧的名称,因为这样做会导致名称冲突?

    我认为在这种情况下,两者都可能存在,但出于您的目的,我更愿意将其作为一个警示性的例子。它在此处导致错误的事实表明,它可能不是最佳做法。

    根据我的经验,R不能很好地管理名称空间(例如,与Python相比)。因此,tree的作者(有意或无意)引入与 df -这是dataframe常用的一次性名称-如果事实上是这样的话(请参阅此处的注释和问题中的注释;尚不清楚这是data.frame名称中的冲突还是eval()的不当使用导致了数据之间的冲突。框架对象和函数)。

    尽管如此,这是一个很好的例子,说明了名称空间的重要性,并(IMO)提示了如何编写更好的R代码。我认为名称空间正被引入到R生态系统中,但我对R的经验是,有很多名称空间“平坦”,并且有很多名称冲突的机会。因此,我建议您将此作为为自己的变量使用更具描述性/唯一性标识符的原因。这避免了类似您遇到的冲突,并提供了一些未来验证,以帮助避免在包内部发生更改时冲突蔓延到以前的工作代码中。

        2
  •  2
  •   Paul Rougieux    5 年前

    因为潜在的名称冲突会使错误更难调试,所以我强迫自己使用 dtf 而不是 df 很长一段时间。然而,tidyverse中重要的软件包集合似乎可以使用 df公司 例如,在他们的测试中无处不在 test-select.r :

      df <- tibble(g = 1:3, x = 3:1) %>% group_by(g)
    

    我一直在使用 df公司 最近给python起了很多名字 数据帧。所以我倾向于使用 df公司 现在在R也一样。让我们看看这会不会反过来。

    平面或嵌套命名空间

    名称空间问题不是原始问题的一部分,但它与此名称冲突问题有关 df公司 。在探索性数据分析中使用平面名称空间更容易且有趣,您只需直接调用所有函数,但它可能会导致冲突。嵌套的命名空间使调试更加可靠,但代价是更加繁琐,因为您必须在每个函数调用之前加上包名。

    在python中,名称空间冲突不是什么问题,因为它有一个更嵌套的命名空间。比如你 import numpy as np 并在所有numpy函数调用前加上前缀 np 例如 np.array() (这是可能的 from numpy import * 但是 it is frowned upon linters 通常会抱怨)。

    在R中,您必须将探索性数据分析中使用的垃圾代码与要重用的更持久的代码区分开来。在第二种情况下,如果只使用另一个包中的一个或几个函数,最好不要导入该包 library(package_name) 但要调用真正需要的函数 package_name::function