J. *_*ini 3 attributes r object
考虑以下愚蠢的输入和输出:
> names(function(x) x*x)<-"square"
Error in names(function(x) x * x) <- "square" :
target of assignment expands to non-language object
Run Code Online (Sandbox Code Playgroud)
隐含地,这个错误表明它function(x) x * x是一个对象,但是一个非语言对象。然而,文档names()说它允许“一个 R 对象”作为它的输入,这与这个前提相矛盾。此外,语言定义说“在 R 中函数是对象”,这进一步混淆了问题。最后,is.object(function(x) x * x)返回FALSE,但我认为这是出于课堂原因。
我的问题是:什么是对象,为什么names()将其function(x) x * x视为不是对象?
您得到的错误不是由于function对象的性质,而是由于参数names<-是“匿名”对象而不是已链接到符号的对象。考虑一下:
names(1:10)<-letters[1:10]
#Error in names(1:10) <- letters[1:10] :
# target of assignment expands to non-language object
Run Code Online (Sandbox Code Playgroud)
相同的输出。在错误中,non-language看起来像是说“不是符号”的一种非常复杂的方式。但是,您有错误是很合乎逻辑的,因为您正在调用替换函数并且您要求替换其内容的符号不存在。从根本上讲,它与<-运算符有关,它期望赋值的左侧是符号(语言对象)而不是“标准”对象:
1:10<-setNames(1:10,letters[1:10])
#Error in 1:10 <- setNames(1:10, letters[1:10]) :
# target of assignment expands to non-language object
Run Code Online (Sandbox Code Playgroud)
又是同样的错误。
这当然有效:
a<-1:10
names(a)<-letters[1:10]
Run Code Online (Sandbox Code Playgroud)
进入你的例子:
f<-function(x) x*x
names(f)<-"square"
# Error in names(f) <- "square" : names() applied to a non-vector
Run Code Online (Sandbox Code Playgroud)
如果names<-使用“匿名”函数显式调用,则会出现上述错误:
"names<-"(function(x) x*x, "square")
# Error: names() applied to a non-vector
Run Code Online (Sandbox Code Playgroud)
现在错误是由于这样一个事实names<-,虽然是泛型,但没有函数的方法。这记录在?names, 详细信息部分:
'names' 是通用访问器函数,而 'names<-' 是通用替换函数。默认方法获取和设置向量(包括列表)或配对列表的“名称”属性。
我只是针对主要问题添加了几行:“什么是对象”。在 R 中,一切都是对象。该is.object函数有一个误导性的名称,更好的名称应该是is.internalobjectbitset. 该文档非常清楚。标题说:“对象是'内部分类'吗?” 而不是“变量是对象吗?”;在参数部分,因为x它说: x: object to be tested,如果你想首先测试是否x是一个对象,这很奇怪。它还指定主要用于内部使用,而不是作为定义什么是对象的方式(这将是一个愚蠢的函数,因为在 R 中一切都是对象)。
在评论之后,我要补充一点,总而言之,文档没有说明,虽然您可以应用于names任何 R 对象,但您不能分配names给某些类型。在我看来,这是一个非常小的问题,因为names它不仅仅是一个普通的属性,而且与语言的某些属性特别是子集非常相关。只有可以是子集的对象才能有名称。函数对象并不意味着是子集,因此 R 阻止分配一个基本上没有用的名称属性。
{"is.null", do_is, NILSXP, 1, 1, {PP_FUNCALL, PREC_FN, 0}},
{"is.logical", do_is, LGLSXP, 1, 1, {PP_FUNCALL, PREC_FN, 0}},
{"is.integer", do_is, INTSXP, 1, 1, {PP_FUNCALL, PREC_FN, 0}},
{"is.double", do_is, REALSXP,1, 1, {PP_FUNCALL, PREC_FN, 0}},
{"is.complex", do_is, CPLXSXP,1, 1, {PP_FUNCALL, PREC_FN, 0}},
{"is.character", do_is, STRSXP, 1, 1, {PP_FUNCALL, PREC_FN, 0}},
{"is.symbol", do_is, SYMSXP, 1, 1, {PP_FUNCALL, PREC_FN, 0}},
{"is.name", do_is, SYMSXP, 1, 1, {PP_FUNCALL, PREC_FN, 0}},
{"is.environment",do_is, ENVSXP, 1, 1, {PP_FUNCALL, PREC_FN, 0}},
{"is.list", do_is, VECSXP, 1, 1, {PP_FUNCALL, PREC_FN, 0}},
{"is.pairlist", do_is, LISTSXP,1, 1, {PP_FUNCALL, PREC_FN, 0}},
{"is.expression", do_is, EXPRSXP,1, 1, {PP_FUNCALL, PREC_FN, 0}},
{"is.raw", do_is, RAWSXP, 1, 1, {PP_FUNCALL, PREC_FN, 0}},
{"is.object", do_is, 50, 1, 1, {PP_FUNCALL, PREC_FN, 0}},
{"isS4", do_is, 51, 1, 1, {PP_FUNCALL, PREC_FN, 0}},
{"is.numeric", do_is, 100, 1, 1, {PP_FUNCALL, PREC_FN, 0}},
{"is.matrix", do_is, 101, 1, 1, {PP_FUNCALL, PREC_FN, 0}},
{"is.array", do_is, 102, 1, 1, {PP_FUNCALL, PREC_FN, 0}},
{"is.atomic", do_is, 200, 1, 1, {PP_FUNCALL, PREC_FN, 0}},
{"is.recursive", do_is, 201, 1, 1, {PP_FUNCALL, PREC_FN, 0}},
{"is.call", do_is, 300, 1, 1, {PP_FUNCALL, PREC_FN, 0}},
{"is.language", do_is, 301, 1, 1, {PP_FUNCALL, PREC_FN, 0}},
{"is.function", do_is, 302, 1, 1, {PP_FUNCALL, PREC_FN, 0}},
...
Run Code Online (Sandbox Code Playgroud)
表明objects(50) 是一个特定类型,不同于function(302) 或其他类型 ( numeric,matrix ,...)
这证实了的定义do_is中coerce.c:
case 50: /* is.object */
LOGICAL0(ans)[0] = OBJECT(CAR(args));
break;
Run Code Online (Sandbox Code Playgroud)
对象有以下方法:
/* Objects */
{"inherits", do_inherits, 0, 11, 3, {PP_FUNCALL, PREC_FN, 0}},
{"UseMethod", do_usemethod, 0, 200, -1, {PP_FUNCALL, PREC_FN, 0}},
{"NextMethod", do_nextmethod, 0, 210, -1, {PP_FUNCALL, PREC_FN, 0}},
{"standardGeneric",do_standardGeneric,0, 201, -1, {PP_FUNCALL, PREC_FN, 0}},
Run Code Online (Sandbox Code Playgroud)
其中指向基础 R 文档:
R 拥有简单的通用函数机制,可用于面向对象的编程风格。方法分派基于泛型函数的第一个参数的类或作为 UseMethod 或 NextMethod 的参数提供的对象的类进行。
这表明由 检测到的类型 50 的对象is.object只是 S3 类或 S4 类,并由is.object文档确认:
is.object- 对象是内部分类的吗?如果对象 x 设置了 R 内部 OBJECT 位,则返回 TRUE,否则返回 FALSE。OBJECT 位在“class”属性被添加和移除时被设置,因此这是一种检查对象是否具有类属性的非常有效的方法。(S4 对象总是应该的。)
简而言之:内部对象具有class属性集。
与通用语言中的对象相比,这是相当严格的。不确定 R 文档objects(50)在谈论对象时总是意味着什么。
关于names(function())错误,请参阅@nicola 的澄清。