Edward
Edward

Reputation: 18683

Suppressing the column classes for "tibbles"

How do you suppress the column classes when displaying tibbles? For example,

> cars <- as_tibble(mtcars)
> cars
# A tibble: 32 x 11
     mpg   cyl  disp    hp  drat    wt  qsec    vs    am  gear  carb
   <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>  # <-- I don't want to show this row
 1  21       6  160    110  3.9   2.62  16.5     0     1     4     4
 2  21       6  160    110  3.9   2.88  17.0     0     1     4     4
 3  22.8     4  108     93  3.85  2.32  18.6     1     1     4     1
 4  21.4     6  258    110  3.08  3.22  19.4     1     0     3     1
 5  18.7     8  360    175  3.15  3.44  17.0     0     0     3     2
 6  18.1     6  225    105  2.76  3.46  20.2     1     0     3     1
 7  14.3     8  360    245  3.21  3.57  15.8     0     0     3     4
 8  24.4     4  147.    62  3.69  3.19  20       1     0     4     2
 9  22.8     4  141.    95  3.92  3.15  22.9     1     0     4     2
10  19.2     6  168.   123  3.92  3.44  18.3     1     0     4     4
# ... with 22 more rows

Is there a global option? Something along the lines of options("show.tibble.column.classes"=FALSE).

I'd also like to remove them for all output created from a tibble (tbl_df).

> count(cars, cyl)
# A tibble: 3 x 2
    cyl     n
  <dbl> <int>  # <-- omit this row totally.
1     4    11
2     6     7
3     8    14

Upvotes: 4

Views: 1060

Answers (2)

robertspierre
robertspierre

Reputation: 4361

I ended up with the following function to print a tibble.

It will remove metadata (tibble shape, column types), row numbers, and optionally print header and footer separator.

#' Print a tibble
#'
#' @param df The tibble to print
#' @param header Whether to print the header
#' @param header_sep Whether to print a header separator
#' @param footer_sep Whether to print a footer separator
#' @param max_rows The maximum number of rows to print
#'
#' @return None
#'
#' @export
print_tibble <- function(df,
                         header = TRUE,
                         header_sep = TRUE,
                         footer_sep = TRUE,
                         max_rows = 1000) {
  # Remove tibble dimensions (row 1) and column types (row 3)
  # Remove also column header (row 2) if user chooses so
  # See: https://stackoverflow.com/a/64747799/1719931
  if (!header) {
    to_rem <- c(-1, -2, -3)
  } else {
    to_rem <- c(-1, -3)
  }
  txt <- R.utils::captureOutput(
    cat(format(as_tibble(df),n=max_rows)[to_rem], sep = "\n"),
    collapse = "\n"
  )
  # Remove backticks (`)
  txt <- stringr::str_replace_all(txt, r"(`(.+?)`)", r"(\1  )")
  # Remove double quotes (")
  txt <- stringr::str_replace_all(txt, '"', "")
  # Remove spaces at string start
  # reg_spaces <- stringr::regex(r'(^\s+)', multiline = TRUE)
  # txt <- stringr::str_replace_all(txt, reg_spaces, "")
  # Remove row numbers
  # WARNING: This will leave spaces at string start for table rows,
  # which are needed for formatting
  # So must be executed after removing spaces at string start
  reg_dec <- stringr::regex(r'(^\s*\d+(?=\s))', multiline = TRUE)
  txt <- stringr::str_replace_all(txt, reg_dec, \(x) paste0(rep(" ", nchar(x)), collapse=""))
  # Split rows
  rows <- stringr::str_split(txt, "\n")[[1]]
  # Remove spaces at string end (otherwise we are going to have problems when we join)
  reg_spaces <- stringr::regex(r'(\s+$)', multiline = TRUE)
  rows <- stringr::str_replace_all(rows, reg_spaces, "")
  # Build header separator
  slen <- stringr::str_length(stringr::str_match("   ciao", r"(^\s+)")[[1,1]])
  spaces <- paste0(rep(" ", times = slen), collapse = "") 
  hlen <- stringr::str_length(rows[[1]])
  sep <- paste0(rep("-", times = hlen), collapse = "")
  sep <- paste0(spaces, sep, "\n")
  cat(paste0(rows[[1]], "\n"))
  if (header_sep) {
    cat(sep)
  }
  if (nrow(df) > 2) {
    cat(paste0(rows[2:(length(rows) - 1)], collapse = "\n"))
    cat("\n")
    if (footer_sep) {
      cat(sep)
    }
    cat(paste0(rows[[length(rows)]], "\n"))
  } else {
    cat(paste0(rows[[2]], "\n"))
  }
}

Example:

enter image description here

Upvotes: 1

ekoam
ekoam

Reputation: 8844

Is this what you want?

cat(format(as_tibble(mtcars))[-3L], sep = "\n")

Output

# A tibble: 32 x 11
     mpg   cyl  disp    hp  drat    wt  qsec    vs    am  gear  carb
 1  21       6  160    110  3.9   2.62  16.5     0     1     4     4
 2  21       6  160    110  3.9   2.88  17.0     0     1     4     4
 3  22.8     4  108     93  3.85  2.32  18.6     1     1     4     1
 4  21.4     6  258    110  3.08  3.22  19.4     1     0     3     1
 5  18.7     8  360    175  3.15  3.44  17.0     0     0     3     2
 6  18.1     6  225    105  2.76  3.46  20.2     1     0     3     1
 7  14.3     8  360    245  3.21  3.57  15.8     0     0     3     4
 8  24.4     4  147.    62  3.69  3.19  20       1     0     4     2
 9  22.8     4  141.    95  3.92  3.15  22.9     1     0     4     2
10  19.2     6  168.   123  3.92  3.44  18.3     1     0     4     4
# ... with 22 more rows

Explanations

?tibble::print.tbl shows that the class tbl_df is associated with the following format method:

Usage

## S3 method for class 'tbl_df'
format(x, ..., n = NULL, width = NULL, n_extra = NULL)

The format method converts a tibble into a character vector, each element of which is a line to be printed. The third line is for variable types. To get the desired output, we just need to remove that line and cat() the rest as is.

Upvotes: 7

Related Questions