1

I want a little helper to prepend a timestamp for each debug statement. I'm not looking to use a logger library. Here is the attempt:

tp = function(...) {
  ts = format(Sys.time(), "%d.%m.%Y %H:%M:%OS")
  m = paste('[',ts,']',str(...))
  print(m)
}

When invoking the helper tp to print the columns of a data.frame :

 tp(names(df))

The intended output is this:

[ 04.03.2020 19:35:00.345 ]  country state day dt confirmed recovered deaths

But the actual output is:

 chr [1:7] "country" "state" "day" "dt" "confirmed" "recovered" "deaths"
[1] "[ 04.03.2020 19:35:00.345 ] "

Note that I added

 str(...)

because otherwise the output is one line per column element. Instead the output should keep the printing on one line: maybe via joining the collection items some way? I could use some help on cleaning this up.

WestCoastProjects
  • 58,982
  • 91
  • 316
  • 560

2 Answers2

3

You need to paste together the ellipsis arguments into a single string.

tp = function(...) {
  ts = format(Sys.time(), "%d.%m.%Y %H:%M:%OS")
  m = paste('[', ts, ']', paste(..., collapse = " "))
  print(m)
}

df <- data.frame("country" = NA,
                 "state" = NA,
                 "day" = NA)

tp(names(df))
#> [1] "[ 05.03.2020 08:10:58 ] country state day"
caldwellst
  • 5,719
  • 6
  • 22
2

You probably actually want cat, not print.

Then you could define:

tp = function(...) {
  cat(format(Sys.time(), "[ %d.%m.%Y %H:%M:%OS ]"), ...)
  return(invisible())
}

tp(names(df))
# [ 05.03.2020 12:03:13.015595 ] country state day

Notice the lack of [1] "..."

FWIW R has date() built in which has a different format but is more concise:

cat(date())
# Thu Mar  5 04:04:37 2020

Or, if you don't need subsecond accuracy and are fine with ISO formatting, format = '[ %F %T ]' is also more concise.

You might also consider using %z and/or the tz argument to format.POSIXct to convey the system time zone in your log as well.

MichaelChirico
  • 33,841
  • 14
  • 113
  • 198
  • thx i had just inquired about removing the extra fanfare; that takes care of it – WestCoastProjects Mar 05 '20 at 04:06
  • did you try it out? I see a `NULL` at the end `4.03.2020 20:13:05.224] country state day dt confirmed recovered deathsNULL` – WestCoastProjects Mar 05 '20 at 04:09
  • @javadba you might check https://stackoverflow.com/q/31843662/3576984 or https://stackoverflow.com/q/12775085/3576984 for some more details about `cat` vs `print`. In sum, `cat` is ideal for logging (straight to `stdout`), `print` is more about understanding/displaying structures in R. – MichaelChirico Mar 05 '20 at 04:09
  • re `NULL` my bad I did not replace `print` with `return`. It works as you show. – WestCoastProjects Mar 05 '20 at 04:11
  • yep -- the return value of `cat` is `NULL` (ditto for `invisible()`) -- see `x=cat(1, 2, 3); print(x)`. You may want to add a `cat('\n')` to force carriage return as well, or put `'\n'` after `...`. – MichaelChirico Mar 05 '20 at 04:13
  • thx. you'll be hearing from novice-R-me more .. well actually .. _v_ soon – WestCoastProjects Mar 05 '20 at 04:18