daroczig/logger

How to log the contents of a dataframe?

Closed this issue · 3 comments

Hi! Sorry if this is a dumb question, but I want to do something like:

dropped_rows <- grouped_clean_data %>% select(date, idx, n_days) %>% filter(n_days <7)
if (nrow(dropped_rows) > 0){
  log_warn("Dropping the following weeks due to incomplete data:")
  log_warn("{dropped_rows}")
}

But this ... doesn't work. What's the recommend way to achieve something like this?

You can transform your data frame to strings before passing to logger, or do that automatically eg via formatter_pander from #22 -- will try to merge that later this week.

The above PR was merged, so now you should be able to use formatter_pander to easily log data frames.

what about something like this?

formatter_format_paste <- function (..., 
                                    .logcall = sys.call(), .topcall = sys.call(-1), 
                                    .topenv = parent.frame()) {
  
  # format items using generic function and collapse with newline
  args <- unlist(lapply(list(...), function(x) {
    if (is.data.frame(x)) {
      s <- paste(format(tibble::as_tibble(x)), collapse = '\n')
    } else{
      s <- paste(format(x), collapse = '\n')
    }
    s
  }))
  
  # insert ' ' if previous item does not end with '\n'
  for (i in utils::head(seq_len(length(args)), -1)) {
    s <- args[i]
    n <- nchar(s)
    if (substr(s, n, n) != '\n') {
      args[i] <- paste0(s, ' ')
    }
  }
  
  paste(args, collapse = "")
}

log_formatter(formatter_format_paste)
> log_info(datasets::cars, '\n', 'abc')
INFO [2023-07-11 10:09:51] # A tibble: 50 x 2
   speed  dist
   <dbl> <dbl>
 1     4     2
 2     4    10
 3     7     4
 4     7    22
 5     8    16
 6     9    10
 7    10    18
 8    10    26
 9    10    34
10    11    17
# ... with 40 more rows
# i Use `print(n = ...)` to see more rows 
abc