How to let print() pass arguments to a user defined print method in R?

笑着哭i 提交于 2021-02-19 04:42:52

问题


I have defined an S3 class in R that needs its own print method. When I create a list of these objects and print it, R uses my print method for each element of the list, as it should.

I would like to have some control over how much the print method actually shows. Therefore, the print method for my class takes a few additional arguments. However, I have not found a way to make use of these arguments, when printing a list of objects.

To make this more clear, I give an example. The following code defines two objects of class test, a list that contains both objects and a print method for the class:

obj1 <- list(a = 3, b = 2)
class(obj1) <- "test"
obj2 <- list(a = 1, b = 5)
class(obj2) <- "test"
obj_list <- list(obj1, obj2)

print.test <- function(x, show_b = FALSE, ...) {
  cat("a is", x$a, "\n")
  if (show_b) cat("b is", x$b, "\n")
}

Printing a single object works as expected:

print(obj1)
## a is 3 
print(obj2, show_b = TRUE)
## a is 1 
## b is 5

When I print obj_list, my print method is used to print each object in the list:

print(obj_list)
## [[1]]
## a is 3 
## 
## [[2]]
## a is 1 

But I would like to be able to tell print() to show b also in this situation. The following (a bit naive...) code does not produce the desired result:

print(obj_list, show_b = TRUE)
## [[1]]
## a is 3 
## 
## [[2]]
## a is 1

Is it possible to print obj_list and at the same time pass the argument show_b = TRUE to print.test()? How?


回答1:


Following Josh's suggestion, I found a way to avoid print.default() being called when printin a list. I simply wrote a print method for lists, since none seems to exist as part of base R:

print.list <- function(x, ...) {

  list_names <- names(x)
  if (is.null(list_names)) list_names <- rep("", length(x))

  print_listelement <- function(i) {
    if (list_names[i]=="") {
      cat("[[",i,"]]\n", sep="")
    } else {
      cat("$", list_names[i], "\n", sep="")
    }
    print(x[[i]], ...)
    cat("\n")
  }

  invisible(lapply(seq_along(x), print_listelement))

}

The relevant part is that ... is passed on to print, when the objects inside the list are printed. So now, coming back to the example in the question, printing a list of test objects works together with show_b =TRUE:

print(obj_list, show_b = TRUE)
## [[1]]
## a is 3 
## b is 2 
## 
## [[2]]
## a is 1 
## b is 5 

However, I am a bit uncomfotable with defining print.list myself. Chances are that it is not working as well as the built-in printing mechanism for lists.



来源:https://stackoverflow.com/questions/31856189/how-to-let-print-pass-arguments-to-a-user-defined-print-method-in-r

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!