itsMeInMiami
itsMeInMiami

Reputation: 2659

Can I print tibbles in Rmarkdown / xaringan so they look like the RStudio console

If I print a tibble with the console in the RStudio IDE the NA values appear in red. When I print the table on a xaringan slide the table is black and white and the NA_character_ values display as <NA>. Is there a way to get the output on a xaringan slide to look like the console output (without using a screen shot)?

Here is an example:

---
title: "x"
output:
  xaringan::moon_reader
---


```{r}
library(tibble)
example <- tribble(
  ~name, ~age,
  "Fran", 2,
  "Bob", NA,
  NA, NA
)
example
```

Upvotes: 5

Views: 752

Answers (2)

lroha
lroha

Reputation: 34441

This is available via the fansi package which provides knitr hooks for rendering crayon output into HTML in rmarkdown. More info in the vignette here.

```{r setup, echo = FALSE, results='asis'}

options(crayon.enabled = TRUE)

old.hooks <- fansi::set_knit_hooks(knitr::knit_hooks)

```

```{r}

tibble::tribble(
  ~name, ~age,
  "Fran", 2,
  "Bob", NA,
  NA, NA
)

waldo::compare(1:5, 3:7)

```

enter image description here

Upvotes: 5

Kat
Kat

Reputation: 18714

I tried to account for 'I didn't know what I didn't know' in regards to where your R Markdown script goes down the line (as you add more content). This works for what you have here, in addition to looking for coded negative numbers.

I have the styling called out individually. If you want to update/change these styles, you should be able to see what and where to change the styles from how this is written. I added comments to the Javascript, as well.

  1. I used the same YAML as you have above.

  2. I updated example so that it would contain a negative number. That way you can see that negative numbers will change color, as well.

    library(tibble)
    example <- tribble(
      ~name, ~age,
      "Fran", 2,
      "Bob", NA,
      NA, NA,
      "George", -1
    )
    example
    

Add this chunk anywhere inside your R Markdown script file.

```{r doAsYouAreTold,results="asis",echo=FALSE,engine="js"}
// var str = text.innerHTML,
// reg = /red|blue|green|orange/ig; //g is to replace all occurrences

text = document.querySelectorAll("pre>code.remark-code:not(.hljs)>div.remark-code-line");

for (i = 0; i < text.length; ++i) {
  str = text[i].innerHTML,
  reg = /NA|##|-[0-9]+|&lt;chr&gt;|&lt;dbl&gt;|&lt;int&gt;|&lt;fct&gt;|&lt;num&gt;/ig; 
        //g is to replace all occurrences
   // fix the structure
  toStr = String(reg);
  color = (toStr.replace('\/g', '|')).substring(1);

  //split the list
  colors = color.split("|");
  
  //remove the <> around NA
  str = str.replace(/&lt;NA&gt;/g, 'NA  '); // added whitespace to keep spacing even
  
  //remove the ## preceding each code line
  str = str.replace(/##/g, '');
  
  // look for negative numbers - make them dark red
  if(colors.indexOf("-[0-9]+") > -1) {
    str = str.replace(/(-[0-9]+)/g, '<span style="color:darkred;">$1</span>');
  }
  
  // look for NA - make them dark red
  if (colors.indexOf("NA") > -1) {
    str = str.replace(/NA/g, '<span style="color:darkred;">NA</span>');
  }
  
  // look for field types - make them italicized and the color gray
  if (colors.indexOf("&lt;chr&gt;") > -1) {
    str = str.replace(/&lt;chr&gt;/g, '<i style="color:gray;">&lt;chr&gt;</i>');
  }
  if (colors.indexOf("&lt;dbl&gt;") > -1) {
    str = str.replace(/&lt;dbl&gt;/g, '<i style="color:gray;">&lt;dbl&gt;</i>');
  }
  if (colors.indexOf("&lt;int&gt;") > -1) {
    str = str.replace(/&lt;int&gt;/g, '<i style="color:gray;">&lt;int&gt;</i>');
  }
  if (colors.indexOf("&lt;fct&gt;") > -1) {
    str = str.replace(/&lt;fct&gt;/g, '<i style="color:gray;">&lt;fct&gt;</i>');
  }
  if (colors.indexOf("&lt;num&gt;") > -1) {
    str = str.replace(/&lt;num&gt;/g, '<i style="color:gray;">&lt;num&gt;</i>');
  }
  
  // replace the updated content of str
  text[i].innerHTML = str;
}

// look for A tibble (A tsibble.. A ... anything else that could land here)
// make the text gray
text2 = document.querySelectorAll("pre>code.remark-code>div.remark-code-line:First-child");
for(j = 0; j < text2.length; ++j) {
  if(text2[j].innerText.includes("# A")) {
    str2 = text2[j].innerHTML
    text2[j].innerHTML = '<span style="color:gray;">'+str2+'</span>';
  }
}

```

Before and After the Javascript Chunk is Added

enter image description here enter image description here

Upvotes: 2

Related Questions