Search code examples
rdataframeansi-colorscrayon

How to print a R dataframe with colors?


With the crayon package, one can create colored strings:

library(crayon)
dat <- data.frame(X=c(yellow("foobar"), green("baz")), Y = cyan("qux"))

Here is the encoded dat:

> dat
                       X                   Y
1 \033[33mfoobar\033[39m \033[36mqux\033[39m
2    \033[32mbaz\033[39m \033[36mqux\033[39m

With write.table, one can get the table with the colors:

enter image description here

But the alignment is lost. How to get the colored dataframe with a nice alignment?

The colorDF package allows to set colors in a dataframe, but does not allow to do what I want. What I want is to be able to color one word say in red at every occurrence of this word in a column. The df_search function of colorDF is close to what I want, but it colors the entire cells where the pattern is found, I want to color one word only.

For example, in this dataframe:

#                                file line              code
# 1                        folder/f.R    1 f <- function(x){
# 2              folder/subfolder/g.R    1 g <- function(y){
# 3 folder/subfolder/subsubfolder/h.R    1 h <- function(z){

I want the word function in the code column to be red.


Solution

  • You could use a tibble instead of a data.frame as it allows to print vectors nicely, see vignette("pillar", package = "vctrs").

    In particular :

    You can get basic control over how a vector is printed in a tibble by providing a format() method

    To answer your question, you could create a function_red class extending character, see vignette("s3-vector", package = "vctrs"):

    library(vctrs)
    
    data <- read.table(text="file line code
    'folder/f.R' 1 'f <- function(x){'
    'folder/subfolder/g.R' 1 'g <- function(y){'
    'folder/subfolder/subsubfolder/h.R' 1 'h <- function(z){'
    ",header=T)
    
    function_red <- function(x = character()) {
      vec_assert(x, character())
      new_vctr(x, class = "vctrs_function_red")
    }
    
    format.vctrs_function_red <- function(x,...) {
      gsub("function",crayon::red("function"),vec_data(x))
    }
    
    data$code <- function_red(data$code)
    tibble::tibble(data)
    

    enter image description here