在 的源代码中data.frame,最后三行代码设置属性并返回结果。
...
attr(value, "row.names") <- row.names
attr(value, "class") <- "data.frame"
value
}
Run Code Online (Sandbox Code Playgroud)
在我编写的函数中,结果是由 . 创建的命名列表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"
Run Code Online (Sandbox Code Playgroud)
我希望将“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"
Run Code Online (Sandbox Code Playgroud)
该?class文档提供了一些指导:
许多 R 对象都有一个类属性,即一个字符向量,给出对象继承的类的名称。如果对象没有类属性,则它具有隐式类、“矩阵”、“数组”或 mode(x) 的结果(整数向量具有隐式类“整数”除外)。(函数oldClass和oldClass<-获取和设置属性,也可以直接完成。)
当通用函数 fun 应用于具有类属性 c("first", "second") 的对象时,系统会搜索名为 fun.first 的函数,如果找到,则将其应用于该对象。如果没有找到这样的函数,则会尝试名为 fun.second 的函数。如果没有类名产生合适的函数,则使用函数 fun.default (如果存在)。如果没有class属性,则尝试隐式类,然后使用默认方法。
从这里并运行一些简单的测试,我得出结论:
attributes(list(1)),typeof(list(1))print在列表上调用时,它使用print.defaultprint.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"
Run Code Online (Sandbox Code Playgroud)