在data.frame
的源代码中,最后三行代码设置属性并返回结果。
...
attr(value, "row.names") <- row.names
attr(value, "class") <- "data.frame"
value
}
在我编写的函数中,结果是由lapply
创建的命名列表。在我在函数体中设置任何属性之前,结果如下。
> x <- data.frame(a = 1:5, b = letters[1:5])
> (g <- grep.dataframe("a|c", x))
# ...
# $b
# value row
# 1 a 1
# 2 c 3
> attributes(g) # I want "list" in here...
# $names
# [1] "a" "b"
我希望“class”包含在属性列表中,因此我在attr(res, "class") <- "list"
之前添加res
(res
是最终结果)。 “class”现在显示在属性列表中。但是,它也打印出函数的结果,这是我不想要的。我尝试用invisible
包装它,但这不起作用。
为什么手动分配的属性会打印出功能结果,但是在我创建的新数据框中会被抑制?
> (h <- grep.dataframe("a|c", x))
# ...
# $b
# value row
# 1 a 1
# 2 c 3
# attr(,"class") # ...This prints with the result. I don't want that.
# [1] "list"
> attributes(h) # ...But I want these attributes
# $names
# [1] "a" "b"
# $class
# [1] "list"
答案 0 :(得分:3)
?class
文档提供了一些指示:
许多R对象都有一个class属性,一个字符向量给出了对象继承的类的名称。如果对象没有类属性,则它具有隐式类,&#34;矩阵&#34;,&#34;数组&#34;或者模式(x)的结果(除了整数向量具有隐式类&#34;整数&#34;)。 (函数oldClass和oldClass&lt; - 获取并设置属性,也可以直接完成。)
当一个通用函数fun应用于具有类属性c的对象(&#34; first&#34;,&#34; second&#34;)时,系统会搜索名为fun.first的函数,如果它找到它,将它应用于对象。如果没有找到这样的函数,则尝试一个名为fun.second的函数。如果没有类名生成合适的函数,则使用函数fun.default(如果存在)。如果没有class属性,则尝试隐式类,然后使用默认方法。
从那里开始并运行一些简单的测试,我收集到了:
attributes(list(1))
,typeof(list(1))
print
时,它正在使用print.default
print.default
打印对象的属性因此,您可以定义一个print.list
来处理您的特殊情况:
print.list <- function(x, ...) {
if (is.list(x)) attr(x, "class") <- NULL
print.default(x, ...)
}
res <- list(1)
attr(res, "class") <- "list"
res
# [[1]]
# [1] 1
attributes(res)
# $class
# [1] "list"