First of all, thank you jalvesaq for the great package! 🙏🙏
If you'd like to colorize R terminal output you can use {jalvesaq/colorout}
I customize extra color patterns for
- base R: class for
str
- {data.table} : row id, column class
- {mlr3} : R6 field name
Click to enlarge image
Simply install with remotes::install_github('jalvesaq/colorout')
. And it just works out of the box.
Feel free to use these in your .Rprofile
I think it's good idea to generate some popular premade themes for the community and they can further customize them with hex color codes with some helpers together with this awesome package.
- The customized patterns are not perfect as the package has limited regex support (...only two types of regular expression...) (see
?colorout::addPattern
) (for performance, i believe. And it's written in C) and this is my first attempt for customizing the patterns (subject to change). - To customize patterns, see
?colorout::addPattern
- For more info, see {jalvesaq/colorout}
- Premade theme
- Custom theme
- Edit premade themes or customize your brand new theme
- Don't be shy to share with #Rstats community 😎
Pick your theme and copy the codes at the collapsible code section and put them in your .Rprofile
NOTE Focus on the terminal output, as the terminal input is controlled by my terminal.
Put @ .Rprofile
# General ----------------------------------------
colorout::setOutputColors(
index = '\x1b[38;2;76;86;106m',
normal = '\x1b[38;2;216;222;233m',
number = '\x1b[38;2;236;239;244m',
negnum = '\x1b[38;2;180;142;173m',
zero = '\x1b[38;2;136;192;208m', zero.limit = 0.01,
infinite = '\x1b[38;2;236;239;244m',
string = '\x1b[38;2;235;203;139m',
date = '\x1b[38;2;236;239;244m',
const = '\x1b[38;2;136;192;208m',
true = '\x1b[38;2;163;190;140m',
false = '\x1b[38;2;191;97;106m',
warn = '\x1b[38;2;235;203;139m',
stderror = '\x1b[38;2;191;97;106m', error = '\x1b[38;2;191;97;106m',
verbose = FALSE
)
# Custom patterns --------------------------------
# NOTE Do not copy all. Pick what you use/like.
# _ {data.table} ---------------------------------
colorout::addPattern('[0-9]*:', '\x1b[38;2;143;188;187m') # Row num
colorout::addPattern('---', '\x1b[38;2;76;86;106m') # Row splitter
colorout::addPattern('<[A-z]*>', '\x1b[38;2;143;188;187m') # Col class
# _ `str` ----------------------------------------
# List
colorout::addPattern('List of [0-9]*', '\x1b[38;2;235;203;139;48;2;76;86;106;1m')
# Class
colorout::addPattern(' num ', '\x1b[38;2;143;188;187m')
colorout::addPattern(' int ', '\x1b[38;2;143;188;187m')
colorout::addPattern(' dbl ', '\x1b[38;2;143;188;187m')
colorout::addPattern(' chr ', '\x1b[38;2;143;188;187m')
colorout::addPattern(' logi ', '\x1b[38;2;143;188;187m')
colorout::addPattern(' lglc ', '\x1b[38;2;143;188;187m')
colorout::addPattern(' Factor ', '\x1b[38;2;143;188;187m')
colorout::addPattern(' Ord.factor ', '\x1b[38;2;143;188;187m')
colorout::addPattern(' POSIXct, ', '\x1b[38;2;143;188;187m')
colorout::addPattern('function ', '\x1b[38;2;143;188;187m')
colorout::addPattern(' lgcl ', '\x1b[38;2;143;188;187m')
colorout::addPattern(' cplx ', '\x1b[38;2;143;188;187m')
# Misc
colorout::addPattern('$ ', '\x1b[38;2;76;86;106m')
# _ `str`, {mlr3} --------------------------------
# R6 field name
colorout::addPattern('* [A-z]*:', '\x1b[38;2;235;203;139m')
colorout::addPattern("* [A-z]* [A-z]*:", '\x1b[38;2;235;203;139m')
colorout::addPattern("* [A-z]* [A-z]* [A-z]*:", '\x1b[38;2;235;203;139m')
colorout::addPattern("* [A-z]* [A-z]* [A-z]* [A-z]*:", '\x1b[38;2;235;203;139m')
colorout::addPattern('[A-z]* ([0-9]*):', '\x1b[38;2;235;203;139m') # `- dbl (10):`
colorout::addPattern('- [A-z]* ([0-9]*):', '\x1b[38;2;235;203;139m') # `- dbl (10):`
# So on...
...
Put @ .Rprofile
colorout::setOutputColors(
index = '\x1b[38;2;76;86;106m',
normal = '\x1b[38;2;236;239;244m',
number = '\x1b[38;2;236;239;244m',
negnum = '\x1b[38;2;253;151;31m',
zero = '\x1b[38;2;102;217;239m', zero.limit = 0.01,
infinite = '\x1b[38;2;236;239;244m',
string = '\x1b[38;2;230;219;116m',
date = '\x1b[38;2;236;239;244m',
const = '\x1b[38;2;253;151;31m',
true = '\x1b[38;2;166;226;46m',
false = '\x1b[38;2;249;38;114m',
warn = '\x1b[38;2;230;159;102',
stderror = '\x1b[38;2;249;38;114m', error = '\x1b[38;2;249;38;114m',
verbose = FALSE
)
# NOTE Do not copy all. Pick what you use/like.
# _ {data.table} ---------------------------------
colorout::addPattern('[0-9]*:', '\x1b[38;2;117;113;94m') # Row num
colorout::addPattern('---', '\x1b[38;2;117;113;94m') # Row splitter
colorout::addPattern('<[A-z]*>', '\x1b[38;2;117;113;94m') # Col class
# _ `str` ----------------------------------------
# List
colorout::addPattern('List of [0-9]*', '\x1b[38;2;230;219;116;48;2;76;86;106;1m')
# Class
colorout::addPattern(' num ', '\x1b[38;2;117;113;94m')
colorout::addPattern(' int ', '\x1b[38;2;117;113;94m')
colorout::addPattern(' dbl ', '\x1b[38;2;117;113;94m')
colorout::addPattern(' chr ', '\x1b[38;2;117;113;94m')
colorout::addPattern(' logi ', '\x1b[38;2;117;113;94m')
colorout::addPattern(' lglc ', '\x1b[38;2;117;113;94m')
colorout::addPattern(' Factor ', '\x1b[38;2;117;113;94m')
colorout::addPattern(' Ord.factor ', '\x1b[38;2;117;113;94m')
colorout::addPattern(' POSIXct, ', '\x1b[38;2;117;113;94m')
colorout::addPattern('function ', '\x1b[38;2;117;113;94m')
colorout::addPattern(' lgcl ', '\x1b[38;2;117;113;94m')
colorout::addPattern(' cplx ', '\x1b[38;2;117;113;94m')
# Misc
colorout::addPattern('$ ', '\x1b[38;2;76;86;106m')
# _ `str`, {mlr3} --------------------------------
# R6 field name
colorout::addPattern('* [A-z]*:', '\x1b[38;2;174;129;255m')
colorout::addPattern("* [A-z]* [A-z]*:", '\x1b[38;2;174;129;255m')
colorout::addPattern("* [A-z]* [A-z]* [A-z]*:", '\x1b[38;2;174;129;255m')
colorout::addPattern("* [A-z]* [A-z]* [A-z]* [A-z]*:", '\x1b[38;2;174;129;255m')
colorout::addPattern('[A-z]* ([0-9]*):', '\x1b[38;2;174;129;255m') # `- dbl (10):`
colorout::addPattern('- [A-z]* ([0-9]*):', '\x1b[38;2;174;129;255m') # `- dbl (10):`
# So on...
...
colorout::setOutputColors
can be used for full customization without this helper. For more info, see ?colorout::setOutputColors
. If you wish to generate ansi color codes with hex color codes, you can use this helper, for convenience. It's not recommended to put these helpers in .Rprofile. Simply use them separately for generating inputs for colorout::setOutputColors
. If case you'd use them in .Rprofile, make sure to get rid of all the garbage.
Manually get colors in hex format from your favorite theme (ie Nord) and fill them in named list.
Let's do an example with Nord theme. First, get colors from Nord. Then...
#' Helper for generating ansi color codes with hex color codes.
#'
#' After generating ansi color codes, feed input to `colorout::setOutputColors`.
#'
#' @param fg Foreground color in hex format (ie '#000000'). Leave blank for default.
#' @param bg Background color in hex format (ie '#000000'). Leave blank for default.
#' @param fo Formatting (see details)
#'
#' @details
#' Value Formating
#' 0 No formating
#' 1 Bold or bright
#' 2 Faint
#' 3 Italic or inverse
#' 4 Underline
#' 5 Blink slowly
#' 6 Blink quickly
#' 7 Invert
to_ansi <- function(col, fg = '', bg = '', fo = '') {
escape <- '\\x1b['
if (fg != '') fg <- {
rgb_fg <- col2rgb(fg)
paste0("38;2;", rgb_fg[1], ";", rgb_fg[2], ";", rgb_fg[3])
}
if (bg != '') bg <- {
rgb_bg <- col2rgb(bg)
paste0(";48;2;", rgb_bg[1], ";", rgb_bg[2], ";", rgb_bg[3])
}
fo <- if (fo != '') paste0(';', fo)
# Use `cat`, not `paste0`, for correctly printing escape char '\x1b['
cat(col, ': ', escape, fg, bg, fo, 'm', '\n', sep = '')
}
Either
- generate invididual style one-by-one
- Useful for editing one/a few colors of premade themes
- or generate all styles
- Useful for creating brand new themes
to_ansi('white', "#ECEFF4") # white foreground
to_ansi('white_black', "#ECEFF4", "#4C566A") # white foreground, black background
to_ansi('white_black_bold', "#ECEFF4", "#4C566A", 1) # white foreground, black background, bold text
# white: \x1b[38;2;236;239;244m
# white_black: \x1b[38;2;236;239;244;48;2;76;86;106m
# white_black_bold: \x1b[38;2;236;239;244;48;2;76;86;106;1m
Then input the color codes (ie \x1b[38;2;236;239;244m
) to colorout::setOutputColors
- manually
- assign to variables with your R skills & DO NOT forget to
rm
them to avoid contaminating your environments.
or...
# Fill in color names, foreground colors, background colors and formatting (ie bold/italic). For default, leave it blank.
theme <- list(
colors = c('white', 'black', 'snow', 'turquoise', 'dark_red', 'dark_green', 'yellow', 'green', 'red', 'yellow_bold'),
foreground = c("#ECEFF4", "#4C566A", '#D8DEE9', '#88C0D0', "#B48EAD", "#8FBCBB", "#EBCB8B", "#A3BE8C", "#BF616A", "#EBCB8B"),
background = c("", "", "", "", "", "", "", "", "", ""),
formatting = c("", "", "", "", "", "", "", "", "", 1)
)
# - Manually copy & paste color codes (in character type) to `colorout::setOutputColors`. It's okay because you only set it once-and-for-all. Otherwise, you can assign the colors to variables and remove them after calling `colorout::setOutputColors`
# - or assign them to variables AND make sure to remove them after calling `colorout::setOutputColors` because you don't want them to contaminate your environments.
invisible( mapply(to_ansi, theme[[1]], theme[[2]], theme[[3]], theme[[4]]) )
# white: \x1b[38;2;236;239;244m
# black: \x1b[38;2;76;86;106m
# snow: \x1b[38;2;216;222;233m
# turquoise: \x1b[38;2;136;192;208m
# dark_red: \x1b[38;2;180;142;173m
# dark_green: \x1b[38;2;143;188;187m
# yellow: \x1b[38;2;235;203;139m
# green: \x1b[38;2;163;190;140m
# red: \x1b[38;2;191;97;106m
# yellow_bold: \x1b[38;2;235;203;139;1m
# General ----------------------------------------
colorout::setOutputColors(
index = '\x1b[38;2;76;86;106m',
normal = '\x1b[38;2;216;222;233m',
number = '\x1b[38;2;236;239;244m',
negnum = '\x1b[38;2;180;142;173m',
zero = '\x1b[38;2;136;192;208m', zero.limit = 0.01,
infinite = '\x1b[38;2;236;239;244m',
string = '\x1b[38;2;235;203;139m',
date = '\x1b[38;2;236;239;244m',
const = '\x1b[38;2;136;192;208m',
true = '\x1b[38;2;163;190;140m',
false = '\x1b[38;2;191;97;106m',
warn = '\x1b[38;2;235;203;139m',
stderror = '\x1b[38;2;191;97;106m', error = '\x1b[38;2;191;97;106m',
verbose = FALSE
)
# Custom patterns --------------------------------
# NOTE Do not copy all. Pick what you use/like.
# _ {data.table} ---------------------------------
colorout::addPattern('[0-9]*:', '\x1b[38;2;143;188;187m') # Row num
colorout::addPattern('---', '\x1b[38;2;76;86;106m') # Row splitter
colorout::addPattern('<[A-z]*>', '\x1b[38;2;143;188;187m') # Col class
# _ `str` ----------------------------------------
# Class
colorout::addPattern(' num ', '\x1b[38;2;143;188;187m')
colorout::addPattern(' int ', '\x1b[38;2;143;188;187m')
colorout::addPattern(' chr ', '\x1b[38;2;143;188;187m')
colorout::addPattern(' Factor ', '\x1b[38;2;143;188;187m')
colorout::addPattern(' Ord.factor ', '\x1b[38;2;143;188;187m')
colorout::addPattern(' logi ', '\x1b[38;2;143;188;187m')
colorout::addPattern('function ', '\x1b[38;2;143;188;187m')
colorout::addPattern(' dbl ', '\x1b[38;2;143;188;187m')
colorout::addPattern(' lgcl ', '\x1b[38;2;143;188;187m')
colorout::addPattern(' cplx ', '\x1b[38;2;143;188;187m')
# Misc
colorout::addPattern('$ ', '\x1b[38;2;76;86;106m')
# _ `str`, {mlr3} --------------------------------
# R6 field name
colorout::addPattern('* [A-z]*:', '\x1b[38;2;235;203;139m')
colorout::addPattern("* [A-z]* [A-z]*:", '\x1b[38;2;235;203;139m')
colorout::addPattern("* [A-z]* [A-z]* [A-z]*:", '\x1b[38;2;235;203;139m')
colorout::addPattern("* [A-z]* [A-z]* [A-z]* [A-z]*:", '\x1b[38;2;235;203;139m')
# So on...
# Clean up
rm(theme, to_ansi)
My .Rprofile has slightly different styles than above and it works slightly better with my color codes. For example, I prefer minimalistic styles & colors and, it's meant for differentiating things that are supposed to be differentiated. Feel free to use it.
- Codes below works out of the box but the colors do not match the image shown above because...in short...my terminal emulator (Tmux with VSCode. Thanks Kun Ren for introducing me to Tmux & radian) has internal mapping of color codes. Simply learn how to customize colors with
?colorout::setOutputColors
# NOTE 'whitespaces'
# General
colorout::setOutputColors(
index = 8,
normal = 15, # or 10
number = 15,
negnum = 2,
zero = 7, zero.limit = 0.01,
infinite = '\x1b[38;2;178;227;229m',
string = 15,
date = 10,
const = 7,
true = '\x1b[38;2;178;227;229m',
false = '\x1b[38;2;255;161;170m',
warn = '\x1b[38;2;228;202;175m',
stderror = 3, error = 3,
verbose = FALSE
)
# General
colorout::addPattern('[[[0-9]*]]', 4)
# {data.table}
colorout::addPattern('[0-9]*:', 4) # row num
colorout::addPattern('---', 0) # row splitter
colorout::addPattern('<[A-z]*>', 4) # col class
# `str`
# List
colorout::addPattern('List of [0-9]*', c(1, 5, 15))
# Var
# colorout::addPattern('$ [A-z]*:', 10)
# colorout::addPattern('$ [A-z]* [A-z]*:', 10)
# colorout::addPattern('$ [A-z]* *:', 10)
# colorout::addPattern('$ [A-z]*.[A-z]* *:', 10)
colorout::addPattern('[A-z]*:', 10)
colorout::addPattern('[A-z]* [A-z]*:', 10)
colorout::addPattern('[A-z]* *:', 10)
colorout::addPattern('[A-z]*.[A-z]* *:', 10)
# Class
colorout::addPattern(' num ', 4)
colorout::addPattern(' int ', 4)
# colorout::addPattern(' dbl ', 4)
colorout::addPattern(' chr ', 4)
colorout::addPattern(' logi ', 4)
colorout::addPattern(' lgcl ', 4)
colorout::addPattern(' Factor ', 4)
colorout::addPattern(' Ord.factor ', 4)
colorout::addPattern(' POSIXct, ', 4)
colorout::addPattern('function ', 4)
# colorout::addPattern(' cplx ', 4)
# Misc
colorout::addPattern('$', 8)
# colorout::addPattern(': ', '\x1b[38;2;40;44;53m')
# `str`, {mlr3}
# R6 field name
# colorout::addPattern('* [A-z]*:', 10)
# colorout::addPattern("* [A-z]* [A-z]*:", 10)
# colorout::addPattern("* [A-z]* [A-z]* [A-z]*:", 10)
# colorout::addPattern("* [A-z]* [A-z]* [A-z]* [A-z]*:", 10)
colorout::addPattern('[A-z]*:', 10)
colorout::addPattern("[A-z]* [A-z]*:", 10)
colorout::addPattern("[A-z]* [A-z]* [A-z]*:", 10)
colorout::addPattern("[A-z]* [A-z]* [A-z]* [A-z]*:", 10)
colorout::addPattern('[A-z]* ([0-9]*):', 10) # `- dbl (10):`
colorout::addPattern('- [A-z]* ([0-9]*):', 10) # `- dbl (10):`
# mlr3 misc
colorout::addPattern('* ', 0)
Same codes used in screenshots for color validation, if needed.
# {data.table} -----------------------------------
data.table::data.table(
postive_negative_and_near_zero = sample(c(1, - 1, .005), 200, replace = TRUE),
true_false_NA = sample(c(TRUE, FALSE, NA), 200, replace = TRUE))
# {mlr3} -----------------------------------------
library(mlr3)
task <- tsk('iris')
learner <- lrn('classif.rpart')
learner$train(task, row_ids = 1:120)
learner
mlr3::msr("classif.auc")
# base R `str` -----------------------------------
str(iris)
str(diamonds)
str(list(col_a = rnorm(100), list(
col_b = "This is string...",
col_c = c(T, F, T, T, F),
list(col_d = sum)
)))