And*_*rie 46 variables r function
使用具有相同名称的基本R中的函数的变量名称似乎通常被认为是不良的编程习惯.
例如,写作很有诱惑力:
data <- data.frame(...)
df <- data.frame(...)
Run Code Online (Sandbox Code Playgroud)
现在,该函数data在函数df计算f密度函数时加载数据集.
同样,写作很有诱惑力:
a <- 1
b <- 2
c <- 3
Run Code Online (Sandbox Code Playgroud)
这被认为是不好的形式,因为该函数c将组合其参数.
但是:在R函数的主力中lm,计算线性模型data用作参数.换句话说,data成为lm函数内部的显式变量.
那么:如果R核心团队可以对变量和函数使用相同的名称,那么什么阻止了我们凡人呢?
答案不是R会混淆.请尝试以下示例,其中我明确指定了具有名称的变量c.R根本不会对变量和函数之间的区别感到困惑:
c("A", "B")
[1] "A" "B"
c <- c("Some text", "Second", "Third")
c(1, 3, 5)
[1] 1 3 5
c[3]
[1] "Third"
Run Code Online (Sandbox Code Playgroud)
问题:具有与基本R函数同名的变量究竟是什么问题?
Rei*_*son 23
真的没有.在查找函数时,R通常不会搜索对象(非函数对象):
> mean(1:10)
[1] 5.5
> mean <- 1
> mean(1:10)
[1] 5.5
> rm(mean)
> mean(1:10)
[1] 5.5
Run Code Online (Sandbox Code Playgroud)
@Joris和@Sacha所展示的例子是糟糕的编码让你感动的地方.一种更好的写作方式foo是:
foo <- function(x, fun) {
fun <- match.fun(fun)
fun(x)
}
Run Code Online (Sandbox Code Playgroud)
使用时给出:
> foo(1:10, mean)
[1] 5.5
> mean <- 1
> foo(1:10, mean)
[1] 5.5
Run Code Online (Sandbox Code Playgroud)
在某些情况下,这会让你na.omit感到困惑,@ Joris的例子是IIRC,因为使用了标准的,非标准的评估,正在发生这种情况lm().
几个答案也将Tvs TRUE问题与功能问题的掩盖混为一谈.作为T和TRUE不是函数有点超出@Andrie的问题的范围.
Jor*_*eys 18
问题不在于计算机,而在于用户.通常,代码可能变得更难调试.错字很容易制作,所以如果你这样做:
c <- c("Some text", "Second", "Third")
c[3]
c(3)
Run Code Online (Sandbox Code Playgroud)
你得到了正确的结果.但是,如果你在代码某处怀念和类型c(3)来代替c[3],发现错误就不会那么容易.
范围界定还可能导致非常混乱的错误报告.采取以下有缺陷的功能:
my.foo <- function(x){
if(x) c <- 1
c + 1
}
> my.foo(TRUE)
[1] 2
> my.foo(FALSE)
Error in c + 1 : non-numeric argument to binary operator
Run Code Online (Sandbox Code Playgroud)
通过更复杂的功能,这可以引导您进行无处调试.如果您替换c与x上述功能,该错误会读" object 'x' not found".这将使您的编码错误更快.
接下来,它可能导致相当混乱的代码.代码c(c+c(a,b,c))比大脑要求更多c(d+c(a,b,d)).同样,这是一个微不足道的例子,但它可以有所作为.
显然,你也可以得到错误.当你期望一个函数,你将无法得到它,这可能会产生另一组恼人的错误:
my.foo <- function(x,fun) fun(x)
my.foo(1,sum)
[1] 1
my.foo(1,c)
Error in my.foo(1, c) : could not find function "fun"
Run Code Online (Sandbox Code Playgroud)
一个更现实(和现实)的例子,说明这会导致什么问题:
x <- c(1:10,NA)
y <- c(NA,1:10)
lm(x~y,na.action=na.omit)
# ... correct output ...
na.omit <- TRUE
lm(x~y,na.action=na.omit)
Error in model.frame.default(formula = x ~ y, na.action = na.omit,
drop.unused.levels = TRUE) : attempt to apply non-function
Run Code Online (Sandbox Code Playgroud)
如果na.omit <- TRUE代码中出现50行,请尝试弄清楚这里有什么问题...
在@Andrie评论后编辑的答案包括混淆错误报告的示例
Sac*_*amp 11
R对此非常强大,但你可以想办法打破它.例如,考虑这个函数:
foo <- function(x,fun) fun(x)
Run Code Online (Sandbox Code Playgroud)
这仅仅适用fun于x.这不是最漂亮的方式,但你可能会从某人脚本中遇到这种情况.这适用于mean():
> foo(1:10,mean)
[1] 5.5
Run Code Online (Sandbox Code Playgroud)
但是,如果我指定一个新值来表示它中断:
mean <- 1
foo(1:10,mean)
Error in foo(1:10, mean) : could not find function "fun"
Run Code Online (Sandbox Code Playgroud)
这种情况很少发生,但可能会发生.如果同样的事情意味着两件事,那对人们来说也很困惑:
mean(mean)
Run Code Online (Sandbox Code Playgroud)
既然是微不足道使用任何你想要的其他名字,为什么不使用不同的名字,那么基础R的功能呢?此外,对于某些R变量,这变得更加重要.想想重新分配'+'功能!另一个很好的例子是重新分配,T并且F可以打破这么多脚本.
| 归档时间: |
|
| 查看次数: |
6953 次 |
| 最近记录: |