4

Continue from this question. I want to modify the result's column width, but it can't be done without using the kableExtra. If I load the kableExtra package, the image will become text format.

Here's the code:

---
title: "Untitled"
output: 
    pdf_document:
        latex_engine: xelatex
---
```{r echo=FALSE, results='hide', warning=FALSE, message=FALSE}
## Load modules
library(dplyr)
library(tidyr)
library(ggplot2)
options(tinytex.verbose = TRUE)
## Create a local function to plot the z score
varianceChart <- function(df, personNumber) {
  plot <- df %>%
         filter(n == personNumber) %>%
         ggplot() +
         aes(x=zscore, y=0) +
         geom_rect(aes(xmin=-3.32, xmax=-1.96, ymin=-1, ymax=1), fill="orange2", alpha=0.8) + 
         geom_rect(aes(xmin=1.96, xmax=3.32, ymin=-1, ymax=1), fill="olivedrab3", alpha=0.8) +
         geom_rect(aes(xmin=min(-4, zscore), xmax=-3.32, ymin=-1, ymax=1), fill="orangered3") + 
         geom_rect(aes(xmin=3.32, xmax=max(4, zscore), ymin=-1, ymax=1), fill="chartreuse4") +
         theme(axis.title = element_blank(), 
               axis.ticks = element_blank(), 
               axis.text = element_blank(),
               panel.grid.minor = element_blank(),
               panel.grid.major = element_blank()) +
               geom_vline(xintercept=0, colour="black", alpha=0.3) +
               geom_point(size=15, shape=4, fill="lightblue") ##Cross looks better than diamond
  return(plot)
}

## Create dummy data
Person1 <- rnorm(1, mean=10, sd=2) 
Person2 <- rnorm(1, mean=10, sd=2)
Person3 <- rnorm(1, mean=10, sd=2)
Person4 <- rnorm(1, mean=10, sd=2) 
Person5 <- rnorm(1, mean=10, sd=2) 
Person6 <- rnorm(1, mean=6,  sd=1) 

## Add to data frame
df <- data.frame(Person1, Person2, Person3, Person4, Person5, Person6)

## Bring all samples into one column and then calculate stats
df2  <- df %>% gather(key=Person, value=time)
mean <- mean(df2$time)
sd   <- sqrt(var(df2$time))

stats <- df2 %>%
             mutate(n = row_number()) %>%
             group_by(Person) %>%
             mutate(zscore = (time - mean) / sd)

graph_directory <- getwd() #'./Graphs'

## Now to cycle through each Person and create a graph
for(i in seq(1, nrow(stats))) {
  print(i)
  varianceChart(stats, i)

  ggsave(sprintf("%s/%s.png", graph_directory, i), plot=last_plot(), units="mm", width=100, height=20, dpi=1200)
}

## add a markup reference to this dataframe
stats$varianceChart <- sprintf('\\raisebox{-.4\\totalheight}{\\includegraphics[width=0.2\\textwidth, height=20mm]{%s/%s.png}}', graph_directory, stats$n) 

df.table <- stats[, c(1,2,5)]
colnames(df.table) <- c("PersonName", "Timetaken", "VarianceChart")
df.table$note=paste0("This is a note that contaions a lot of strings ",paste0(LETTERS,collapse = ", "))
```

```{r}
library(knitr)
kable(df.table, caption="The last column is too long that can't be shown in single line.")
```

```{r}
library(kableExtra)
kable(df.table,format = "latex") %>%
  kable_styling(full_width=F) %>%
  column_spec(4, width = "4em")
```

The two results are enter image description here

enter image description here

I can't find any way to change the width without using kableExtra. Am I missing something that can solve my problem?

Many thanks.

Darren Tsai
  • 32,117
  • 5
  • 21
  • 51
蔡佳諭
  • 65
  • 1
  • 4
  • Did you try [this solution with the pander package](https://stackoverflow.com/questions/29425499/wrap-long-text-in-kable-table-column)? Or using the [longtable option from the documentation](https://www.rdocumentation.org/packages/knitr/versions/1.28/topics/kable)? There is also the posibility [to turn the page in landscape](https://stackoverflow.com/questions/32265676/longtable-in-a-knitr-pdf-document-using-xtable-or-kable). Another (ugly) solution might be to save the code for the kable table, using regex change it so it wraps the text and than print a chunk using `{r, results = "asis"}` – Annet Feb 24 '20 at 09:12
  • pander package can't control the text align when the image is bigger. – 蔡佳諭 Feb 25 '20 at 02:12
  • The question is about the package kableExtra. But the answer gives me the correct one. Thanks for your help. Thank you. – 蔡佳諭 Feb 25 '20 at 02:15

2 Answers2

11

If you have raw HTML or LaTeX code in the data, remember to put escape = FALSE in kable() to avoid escaping of special characters.

```{r}
library(kableExtra)
kable(df.table, "latex", booktabs = TRUE, escape = FALSE) %>%
  kable_styling(full_width = FALSE) %>%
  column_spec(4, width = "18em")
```

enter image description here

Darren Tsai
  • 32,117
  • 5
  • 21
  • 51
0

You can also control individual column widthd through the align parameter of the kable function:

---
output:
  pdf_document: default
---

```{r}
library(kableExtra)
library(tidyverse)
```

```{r}
test <- tibble(perc = c('4', '34.2'),
               bla = c('bla','blabla'),
               test = c('test', 'test'))
```

```{r}
test %>% kable('latex', 
               escape=F,
               align = c("|p{1cm}","p{1cm}","p{3cm}|"))
```
FZS
  • 243
  • 1
  • 8