0

I have two Windows machines. Both Windows 10. When I run the following code on each, I get two very different outputs:

library(tibble)

sink(file.path(tempdir(), "test.log"), append = FALSE)
     
print(as_tibble(mtcars))

sink()

One machine gives me the expected output: enter image description here

The other machine gives me the same tibble data, but appears to be printing all the crayon color codes: enter image description here

At first I figured it had to be a difference in the version of R or the version of crayon. But I've now synchronized both on R 4.0.3 and crayon 1.3.4. Tibble version is 3.0.4 on both. Not sure what to check next. The second machine initially had later versions of everything. But I reverted back as much as possible, and I'm still getting the color codes.

Anyone have any suggestions on how to diagnose this?

David J. Bosak
  • 1,386
  • 12
  • 22

2 Answers2

1

The colors are controlled by the crayon package. You can query that package for how many colors are supported, e.g.

> crayon::num_ansi_colors()
[1] 8
> crayon::has_color()
[1] TRUE

There are different ways to configure the number of colors. I'd say, setting an environment variable is the best because it will also used in parallel processing, if you even end up using that. So,

> Sys.setenv(R_CLI_NUM_COLORS = 2)
> crayon::num_ansi_colors()
[1] 2
> crayon::has_color()
[1] TRUE

If you set it to one color, then you'll get:

> Sys.setenv(R_CLI_NUM_COLORS = 1)
> crayon::num_ansi_colors()
[1] 1
> crayon::has_color()
[1] FALSE

Now, key here is when there's only one color, there is no ANSI color escape codes produced. Thus, depending on whether or not the current R environment supports colors or not (crayon::has_color()), you'll get ANSI escape codes.

Since you probably only want to limit the number of colors when you're sink():ing, you don't want to set permanently. The easiest is to use withr for this, e.g.

library(tibble)

sink(file.path(tempdir(), "test.log"), append = FALSE)
     
withr::with_envvar(c(R_CLI_NUM_COLORS = 1), { 
  print(as_tibble(mtcars))
})

sink()

That should do it for you.

HenrikB
  • 6,132
  • 31
  • 34
  • I'm honored to receive an answer from you, Henrik. Thanks for all the amazing work you've done with R. In the case at hand, I had to modify your code to make it work in this situation. Setting the environment variable didn't work for me, but setting the options did. Maybe it's a Windows thing. I'll keep your code and post my adjustment below, in case your answer is useful to someone else. – David J. Bosak Apr 04 '21 at 19:27
  • This works for me, but only if I surround "as_tibble(mtcars)" with "print()" as you have written. But it seems to me that `print` wasn't required in the past to get tibble output to a file using sink. Maybe I was just getting lucky and relying on unsupported behavior? – Joel Buursma May 17 '21 at 22:58
0

Based on the great suggestion from @HenrikB, this is the code that finally worked for me:

  library(tibble)
  
  sink(file.path(tempdir(), "test.log"), append = FALSE)
  
  withr::with_options(c("crayon.colors" = 1), { 
    print(as_tibble(mtcars))
  })
  
  sink()

enter image description here

David J. Bosak
  • 1,386
  • 12
  • 22