对于那些不想阅读我的"案例"的人来说,这就是本质:
什么是在何时充分利用命名空间机制的推荐方法
a)只使用贡献包(比如在一些R分析项目中)?
b)关于开发自己的包裹?
如何最好地避免与正式类(在我的情况下主要是引用类)之间的冲突,因为甚至没有与::类(AFAIU)相当的命名空间机制?
这件事情在我脑海中唠叨了大约两年了,但我觉得我没有达到令人满意的解决方案.另外我觉得情况越来越糟.
我们看到CRAN,github,R-Forge等上的包装数量越来越多,这简直太棒了.
在这样一个分散的环境中,组成R的代码库(简单来说就是基础R和贡献R,为简单起见)自然会偏离理想状态而不是鲁棒性:人们遵循不同的约定,有S3,S4如果存在强制执行约定的" 中央清算实例 ",那么事情就不会像它们那样"一致" .没关系.
鉴于上述情况,使用R编写健壮的代码可能非常困难.并非您需要的所有东西都在基础R中.对于某些项目,您最终会加载相当多的贡献包.
恕我直言,这方面最大的问题是命名空间概念在R中使用的方式:R允许简单地写出某个函数/方法的名称而不明确要求它的命名空间(即foovs. namespace::foo).
所以为了简单起见,这就是每个人都在做的事情.但是这样,名称冲突,破坏代码以及重写/重构代码的需要只是时间问题(或者加载的不同包的数量).
充其量,您将了解新添加的包掩盖/重载哪些现有功能.在最坏的情况下,在您的代码中断之前,您将毫无头绪.
几个例子:
(我不记得哪些功能特别导致了这些问题,但如果有兴趣,我愿意再次查询)
令人惊讶的是,这似乎并没有困扰很多程序员.我试图在r-devel上多次提高兴趣,但没有显着的效果.
::运营商的缺点::Dominick Samperi 指出,使用操作员可能会在某些情况下严重影响效率.R命名空间充当其关联包中所有函数的直接环境.换句话说,当函数bar()从包富调用另一个函数时,R首次评估器搜索中的其他功能<environment: namespace:foo>,那么"imports.foo",<environment: namespace:base>,<environment: R_GlobalEnv>,等下键入返回的搜索列表search().
命名空间的一个很好的方面是它们可以使包像行为更好的公民:未经输出的函数<environment: namespace:foo>和函数imports:foo仅可用:(a)foo中的函数; (b)从foo进口的其他包裹; 或(c)通过完全合格的函数调用,如foo:::bar().
或者直到最近才想到......
这个最近的SO问题突出了一个案例,其中通过调用看似无关的函数找到了一个隐藏在其包的名称空间中的函数:
group <- c("C","F","D","B","A","E")
num <- c(12,11,7,7,2,1)
data <- data.frame(group,num)
## Evaluated **before** attaching 'gmodels' package
T1 <- transform(data, group = reorder(group,-num))
## Evaluated **after** attaching 'gmodels
library(gmodels)
T2 <- transform(data, group = reorder(group,-num))
identical(T1, T2)
# [1] FALSE
Run Code Online (Sandbox Code Playgroud)
@Andrie通过指出gmodels从包gdata导入来回答原始问题,包中包含一个 …
以下一致性导致我的R会话崩溃.
在两台机器上测试,Ubuntu和Mac OS X两者都有类似的结果.
简要说明:使用所有NA的因子列
调用write.tabledata.frame.
原始数据集相当大,我设法隔离了有问题的列,然后创建了一个类似的向量,命名PROBLEM_DATA如下,导致相同的崩溃.
有趣的是,有时R崩溃是彻头彻尾的,它只会引发以下错误:
Error in write.table(x, file, nrow(x), p, rnames, sep, eol, na, dec, as.integer(quote), :
'getCharCE' must be called on a CHARSXP
Run Code Online (Sandbox Code Playgroud)
违规数据和电话:
PROBLEM_DATA <- structure(114:116, .Label = c("String1", "String2", "String3", "String4", "String5", "String6",
"String7", "String8", "String9", "String10", "String11", "String12", "String13", "String14", "String15"), class = "factor")
# This will cause a crash
write.table(PROBLEM_DATA, file=path.expand("~/test.csv"))
# This will also crash
write.table(PROBLEM_DATA, file=path.expand("~/test.csv"), fileEncoding="UTF-8")
Run Code Online (Sandbox Code Playgroud)
R version 2.15.3 …Run Code Online (Sandbox Code Playgroud) 使用Python或R中的数据,我们经常加载几个包.在某些情况下,两个包(例如foo和bar)可能各自包含一些功能(例如do_stuff).
在Python中管理它以防止歧义或意外的方式如下:
from foo import do_stuff
from bar import other_function # (does not load/import do_stuff() from bar)
Run Code Online (Sandbox Code Playgroud)
在R中,我看到的所有代码都只导入包含多个library(package_name)语句的整个包.我认为这会导致非常难以捕获的错误.例如,请参阅重新排序因子给出不同的结果,具体取决于加载的包.事实上,即使"没有掩蔽,因为在基础中不存在reorder.factor",也会发生这种情况.
我希望这个问题的一般答案与from package import function上面的代码类似,但事实并非如此.事实上,公认的(也是唯一的)答案只能解释为什么存在这个问题(而不是淡化这种贡献).答案的评论中提供了一种解决方法,但该解决方法特定于该特定函数(reorder).
有一般的方法我只能导入R中特定包的特定功能吗?因此,我可以有意识地明确我的代码中的所有函数调用来自何处,并确保它们执行我认为他们正在做的事情?
我正在尝试以下功能:
stest <- data.frame(group=c("John", "Jane", "James"), mean=c(3, 5, 1))
transform(stest, group = reorder(group, mean))
Run Code Online (Sandbox Code Playgroud)
并期望输出按 排序mean。相反,我得到:
group mean
1 John 3
2 Jane 5
3 James 1
Run Code Online (Sandbox Code Playgroud)
也就是说,与原始数据帧中的顺序相同。
我错过了什么吗?如何通过数据框的数值变量之一正确排序数据框?
周围的建议是关于使用的reorder,但我无法使其按预期工作。任何加载的包都会干扰吗?
我正在学习R并想知道lubridate是否应该从dplyr发出关于屏蔽"union"的消息.
在lubridate之前加载dplyr,我得到一个错误:arrange":
library(dplyr)
Attaching package: ‘dplyr’
The following objects are masked from ‘package:stats’:
filter, lag
The following objects are masked from ‘package:base’:
intersect, setdiff, setequal, union
library(lubridate)
df1 <- data.frame(c1 = "a", c2 = 1)
df2 <- data.frame(c1 = "a", c2 = 2)
union(df1, df2) %>% arrange(c1)
Error in UseMethod("arrange_") :
no applicable method for 'arrange_' applied to an object of class "list"
Run Code Online (Sandbox Code Playgroud)
似乎联合返回一个列表而不是一个data.frame,然后排列就会跳过它:
str(union(df1, df2))
List of 3
$ : Factor w/ 1 level "a": 1
$ : num …Run Code Online (Sandbox Code Playgroud) 我在这里使用的术语可能不正确,请原谅我...
我遇到一种情况,一个程序包“覆盖”另一个程序包加载的同名函数,从而改变了函数的行为(中断)。
具体情况:
X <- data.frame ( y = rnorm(100), x1 = rnorm(100), x2 = rnorm(100) )
library(CausalImpact)
a <- CausalImpact::CausalImpact( X, c(1,75), c(76, 100) ) # works
library(bfast) # imports quantmod which loads crappy version of as.zoo.data.frame
b <- CausalImpact::CausalImpact( X, c(1,75), c(76, 100) ) # Error
Run Code Online (Sandbox Code Playgroud)
我知道该错误来自该函数的两个版本as.zoo.data.frame。有问题的版本是由bfast从“ quantmod”包导入的(请参阅https://github.com/joshuaulrich/quantmod/issues/168)。不幸的是,他们的修补程序无法防止出现此错误。超级烦人。
我可以解决这个特定的问题,但是我想知道是否有一种通用方法可以从搜索路径中“注销”此功能变量。既不detach也不unloadNamespace删除有问题的函数(后相同的行为)。这里和这里都讨论了一个解释和类似的问题,但是我找不到一个通用的解决方案。例如,我宁愿只是删除此函数,而不是克隆并重新编写CausalImpact以处理此行为。
r ×7
namespaces ×3
package ×2
coding-style ×1
crash ×1
environment ×1
function ×1
masking ×1
scoping ×1
sorting ×1
write.table ×1