简体   繁体   中英

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

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?

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM