如果函数名已重新分配给值,R如何知道使用函数?

如果函数名已重新分配给值,R如何知道使用函数?,r,shadowing,R,Shadowing,我知道在命名变量时不使用全局名称空间中的名称是一种很好的做法,但是当您意外地这样做时会发生什么呢 我以为我会失去前一个对象,但R似乎有一些诡计: 打印(sd) #>函数(x,na.rm=FALSE) #>sqrt(var(如果(是向量(x)|是因子(x))x,则为双(x), #>na.rm=na.rm) #> #> sd[1]12.2 sd(1:10) #> [1] 3.02765 现在R知道在全局名称空间中既有一个称为sd的长度为1的双向量,也有一个stats函数sd() 或者当我调用s

我知道在命名变量时不使用全局名称空间中的名称是一种很好的做法,但是当您意外地这样做时会发生什么呢

我以为我会失去前一个对象,但R似乎有一些诡计:

打印(sd)
#>函数(x,na.rm=FALSE)
#>sqrt(var(如果(是向量(x)|是因子(x))x,则为双(x),
#>na.rm=na.rm)
#> 
#> 
sd[1]12.2
sd(1:10)
#> [1] 3.02765
现在R知道在全局名称空间中既有一个称为
sd
的长度为1的双向量,也有一个stats函数
sd()

或者当我调用
sd(1:10)
时,解释器会自动将其扩展到
sd.default()
?但是R如何知道在
sd
上查找默认方法,因为它现在是一个向量?那么存储在内存中不同位置的函数和变量可以用相同的名称引用

显然是用户定义的变量显然是用户定义的变量错误(1:10):找不到
#函数“显然是用户定义的变量”

sd
属于
stats
环境,不属于
globalenv
。调用
sd()
R查找函数
sd
。它不在
globalenv
中,因此它会查看其他环境,直到找到一个函数
sd

这被称为词汇范围界定,哈德利的书中对此进行了解释。可能在本章或本章中。根据名称出现的上下文,R将在一个命名空间或另一个命名空间中查找该名称

例如,表达式
sd(1:10)
是一个调用,调用中的第一个元素必须是函数名。因此,在本例中,R将查找名为
sd
的函数


另一方面,表达式
sd
不是一个调用,而是一个名称,可以是变量名或函数名。在这种情况下,R将首先在名为
sd
的搜索路径中查找第一个对象,无论它是函数还是其他类型的对象。

简单回答:
sd(1:10)
是对函数
sd
的调用。因此R查找名为
sd()
的函数,它在预加载的stats包中找到该函数。您要使用的术语(和标记)是“隐藏”,如“同名变量隐藏函数”。严格地说,函数的名称没有被“重新分配”。很好的参考,我想我更喜欢Lisp-1场景,其中一个名称指向一件事,并且只指向一件事。这样可以减少歧义。但也许R的方法有好处R是高度灵活的。你绝对可以做任何事,即使是糟糕的把戏,它总是管用的。这是它的优点和缺点。作为一个开发者,我确实同意你的观点,但要实事求是地说,无论你写的那些废话是有用的还是方便的,R都能工作;没有括号,R在名为
sd
的搜索路径中查找第一件事,不管它是否是对象的函数,例如
mtcars这是否意味着名称分配到哪个名称空间取决于运行时检查,其中
a我认为这不完全正确,例如运行
a
search()
path解释了它在哪里找到它们(以及为什么它在
sd()
之前找到
sd
),但没有解释为什么它一直在寻找
sd()
,这大概是因为括号表示它被解释为函数调用而不是对象。