kableExtra column_spec width not working - html

I am creating tables that will be rendered using Rmarkdown to HTML. I am using kable and have been experimenting with kableExtra to add features to my tables. I am not able to get the width option in column_spec to work when applying it to all columns in a table:
data.frame(RRmin=1, RRmax=10) %>%
dplyr::rename(`Reportable Range Min` = RRmin, `Reportable Range Max` = RRmax) %>%
kable() %>%
column_spec(1:2, width = "0.5in") %>%
kable_styling(c("bordered", "condensed"), full_width = F)
This gives a table that looks like this.
I can make the width longer and both columns change, but when it goes smaller it does not seem to work. I can make one column smaller but not the other:
data.frame(RRmin=1, RRmax=10) %>%
dplyr::rename(`Reportable Range Min` = RRmin, `Reportable Range Max` = RRmax) %>%
kable() %>%
column_spec(1, width = "0.5in") %>%
kable_styling(c("bordered", "condensed"), full_width = F)
This gives a table that looks like this. The first column was appropriately changed but I cannot get this effect when I'm trying to change the size of both columns. I have tried doing separate column_spec lines for each column, using escape=F and am not sure what to try next.

I have had similar problems with column_spec not working. I was able to find a fix that worked for my purposes by playing with the width_min option. Maybe that will help.
My issue was that none of the columns widths seemed to be adjusted by column_spec, even when I tried all of the options you mention above. The result was that some columns were way too thin. I set width_min="3in" and fixed it. This was not a perfect fix because now I'm left with other column that are too wide, but it at least made my table a little more readable.

This may be a little late, but I've just been working with the kableExtra package, and it seems that your code is now working pretty much as is.
At first I thought it might have something to do with the ordering of the kable_styling component, but it seems not to matter which order it is in. Perhaps it was a bug in the package that has since been fixed. It is also immaterial wether you use column_spec(column = 1:2, width = "2in"), or column_spec(1:2, width = "2in"). Both seem to work well, as do modifications to the columns size. See below:
---
output: pdf_document
---
```{r global_options, include=FALSE}
# Just some setup:
sapply(c("knitr", "tidyverse", "kableExtra"), require, character.only = TRUE)
options(knitr.kable.NA = '', knitr.table.format = "latex")
knitr::opts_chunk$set(fig.path = 'figures/',
echo = FALSE, warning = FALSE, message = FALSE)
opts_chunk$set(echo = FALSE,
message = FALSE,
warning = FALSE,
fig.align = "center",
fig.width = 5,
fig.pos = 'H',
as.is = TRUE)
```
```{r variable-names-table, as.is=TRUE}
# Size example 1; 1.5 inch columns
data.frame(RRmin=1, RRmax=10) %>%
dplyr::rename(`Reportable Range Min` = RRmin, `Reportable Range Max` = RRmax) %>%
kable() %>%
kable_styling(c("bordered", "condensed"), full_width = F) %>%
column_spec(column = 1:2, width = "1.5in")
# Size example 2; 3 inches
data.frame(RRmin=1, RRmax=10) %>%
dplyr::rename(`Reportable Range Min` = RRmin, `Reportable Range Max` = RRmax) %>%
kable() %>%
column_spec(column = 1:2, width = "3in") %>%
kable_styling(c("bordered", "condensed"), full_width = F)
# To set columns 1 and two to different sizes
data.frame(RRmin=1, RRmax=10) %>%
dplyr::rename(`Reportable Range Min` = RRmin, `Reportable Range Max` = RRmax) %>%
kable() %>%
column_spec(column = 1, width = "3in") %>%
column_spec(column = 2, width = "2in") %>%
kable_styling(c("bordered", "condensed"), full_width = F)
```
Just a note for anyone else dealing with the issue. The above will run as an RMD
R version 3.6.1, on mac
RStudio 1.2.1335
kableExtra 1.1.0
knitr 1.25
tidyverse 1.2.1

Simply replace width by width_min!

I'm using Tex Live 2020, and this problem still exists - it appears that column_spec has a bug. All thse examples run without a probllem if I remove the column_spec commands. As soon as I include the column_spec commands, I get a cryptic error which says 'Undefined control sequence, Latex Error: Illegal character in array arg. The description is also cryptic: ...n}|>{\raggedleft\arraybackslash}p{1.5in}}
The control sequence at the end of the top line
of your error message was never \def'ed. If you have
misspelled it (e.g., \hobx), type I and the correct spelling (e.g., I\hbox). Otherwise just continue, and I'll forget about whatever was undefined. Removing the column_spec command fixes the problem.

The fix is to include the array package in the latex preamble. One way of doing this is adding the following lines to your Rmarkdown header:
header-includes:
- \usepackage{array}

Related

How to source a locally stored image for embedding into a table cell in R Shiny?

The below code does a terrific job of rendering a web-sourced image in a cell of the rhandsontable. However, I'd like swap that image with a jpg image I have stored on my computer. I've tried modifying the below as.character(img(src = "...")) to reflect the local directory and filename, with no luck.
Any suggestions for a straightforward way to do this?
I searched for solutions, for example, Display locally-stored image in R Shiny, but they look rather involved given what I thought is the simplicity of what I'm trying to do. Certainly accessing your local drive is easier than reaching out to the Web via API.
Here's the painfully simple image I want to upload (shrunken of course):
Code:
library(magrittr)
library(htmlwidgets)
library(rhandsontable)
library(shiny)
DF = data.frame(
Col_1 = c("Row 1"),
Col_Help = c(
as.character(img(
src = "https://images.plot.ly/language-icons/api-home/python-logo.png",
title = "My first help text",
style = "width: 50px;")
)
),
text = c("Row 1 does xxx"),
stringsAsFactors = FALSE
)
ui <- fluidPage(br(),rHandsontableOutput('my_table'))
server <- function(input, output, session) {
output$my_table <- renderRHandsontable({
rhandsontable::rhandsontable(
DF,
allowedTags = "<em><b><strong><a><big><img>"
) %>%
hot_cols(colWidths = c(200, 80)) %>%
hot_col(1:2, renderer = htmlwidgets::JS("safeHtmlRenderer")) %>%
hot_cols(colWidths = ifelse(names(DF) != "text", 100, 0.1))
})
}
shinyApp(ui, server)
Put your file, say question_mark.jpg in the www folder of your shiny app, and then adjust your DF definition as below:
DF = data.frame(
Col_1 = c("Row 1"),
Col_Help = c(
as.character(img(
src = "question_mark.jpg",
title = "My first help text",
style = "width: 50px;")
)
),
text = c("Row 1 does xxx"),
stringsAsFactors = FALSE
)
Output:

Side-by-Side gt tables **WITH** footnotes

I am trying to create side-by-side gt tables, as the title suggests. I started with the very helpful answer found here: Arrange gt tables side by side or in a grid or table of tables. The key was to ouput the left and right tables as raw html (as_raw_html), then combine in a dataframe, then send back into gt and reformat as markdow (fmt_markdown).
However, I ran into a problem that I couldn't solve. The fmt_markdown command skips the footnote, so the resulting table has the raw html as a footnote.
I checked the documentation for gt, and the fmt_markdown command takes columns and rows as input - but, apparently, the footnote area is considered neither a column nor a row.
So the crux seems to be that I can't seem to find any way to target the footnote area for reformatting as mardown.
Below is a reproducible example.
library(tidyverse)
library(gt)
# Make a table with a footnote
tL <- exibble %>%
select(c(num, char, group)) %>%
gt() %>%
tab_footnote(
footnote = html("**I'm an apricot**"),
locations = cells_body(columns = char,
rows = char == "apricot")
) %>%
tab_style(style = cell_text(color = "blue"),
locations = cells_footnotes()) %>%
as_raw_html()
# Make a copy
tR <- tL
# Side-By-Side
SideBySide <- data.frame(Ltable = tL, Rtable = tR) %>%
gt() %>%
fmt_markdown(columns = everything())
And the result looks like this:
Created on 2022-02-20 by the reprex package (v2.0.1)

Extend width of column with renderDataTable in Shiny

I having trouble understanding the behavior of renderDataTable function using Shiny.
I am trying to extend the width of one specific column.
When I am not using Shiny, and just trying to visualize the output of the table, I write the below and I get the expected output in the plot (Amazon Title column is extended):
Category <- c("Tools & Home Improvement", "Tools & Home Improvement")
AmazonTitle <- c("0.15,Klein Tools NCVT-2 Non Contact Voltage Tester- Dual Range Pen Voltage Detector for Standard and Low Voltage with 3 m Drop Protection", " ABCDFGEGEEFE")
ASIN_url <- c("<a href='https://www.amazon.com/dp/B004FXJOQO'>https://www.amazon.com/dp/B004FXJOQO</a>", "<a href='https://www.amazon.com/dp/B004FXJOQO'>https://www.amazon.com/dp/B0043XJOQO</a>")
ASIN <- c("B004FXJOQO", "B0043XJOQO")
All_ASIN_Information <- data.frame(Category, AmazonTitle, ASIN_url, ASIN)
DT::datatable(All_ASIN_Information, escape=FALSE,
options = list(
pageLength = 20, autoWidth = TRUE,
columnDefs = list(list( targets = 2, width = '600px'))
)
)
But when I use this exact block inside a DT::renderDataTable function for Shiny, the result is different and the column width is not extended....
See behavior for Shiny with below code:
library(shiny)
library(DT)
ui <- fluidPage(
mainPanel(
DT::dataTableOutput("Table_ASIN")))
server <- function(input, output){
output$Table_ASIN <- DT::renderDataTable(
DT::datatable(All_ASIN_Information, escape=FALSE,
options = list(
pageLength = 20, autoWidth = TRUE,
columnDefs = list(list( targets = 2, width = '600px'))
)))
}
shinyApp(ui, server)
I don't know if this behavior is caused by the hyperlinks created in column 'ASIN_url' but I would really need them anyway.
Any help much appreciated on this !
One option would be to shorten the link like this:
ASIN_url <- c("<a href='https://www.amazon.com/dp/B004FXJOQO'>Link</a>", "<a href='https://www.amazon.com/dp/B004FXJOQO'>Link</a>")
Another would be to add a scroll bar by including scrollX = TRUE in the option list

How to get descriptive table for both continuous and categorical variables?

I want to get descriptive table in html format for all variables that are in data frame. I need for continuous variables mean and standard deviation. For categorical variables frequency (absolute count) of each category and percentage of each category. Also I need the count of missing values to be included.
Lets use this data:
data("ToothGrowth")
df<-ToothGrowth
df$len[2]<-NA
df$supp[5]<-NA
I want to get table in html format that will look like this:
----------------------------------------------------------------------
Variables N (missing) Mean (SD) / %
----------------------------------------------------------------------
len 59 (1) 18.9 (7.65)
supp
OJ 30 50%
VC 29 48.33%
NA 1 1.67%
dose 60 1.17 (0.629)
I need also to set the number of digits after decimal point to show.
If you know better variant to display that information in html in better way than please provide your solution.
Here's a programatic way to create separate summary tables for the numeric and factor columns. Note that this doesn't make note of NAs in the table as you requested, but does ignore NAs to calculate summary stats as you did. It's a starting point, anyway. From here you could combine the tables and format the headers however you want.
If you knit this code within an RMarkdown document with HTML output, kable will automatically generate the html table and a css will format the table nicely with a horizontal rules as pictured below. Note that there's also a booktabs option to kable that makes prettier tables like the LaTeX booktabs package. Otherwise, see the documentation for knitr::kable for options.
library(dplyr)
library(tidyr)
library(knitr)
data("ToothGrowth")
df<-ToothGrowth
df$len[2]<-NA
df$supp[5]<-NA
numeric_cols <- dplyr::select_if(df, is.numeric) %>%
gather(key = "variable", value = "value") %>%
group_by(variable) %>%
summarize(count = n(),
mean = mean(value, na.rm = TRUE),
sd = sd(value, na.rm = TRUE))
factor_cols <- dplyr::select_if(df, is.factor) %>%
gather(key = "variable", value = "value") %>%
group_by(variable, value) %>%
summarize(count = n()) %>%
mutate(p = count / sum(count, na.rm = TRUE))
knitr::kable(numeric_cols)
knitr::kable(factor_cols)
I found r package table1 that does what I want. Here is a code:
library(table1)
data("ToothGrowth")
df<-ToothGrowth
df$len[2]<-NA
df$supp[5]<-NA
table1(reformulate(colnames(df)), data=df)

r markdown: data frame (or data.table) goes out of page

I am trying to create an HTML output using R - markdown. The problem is that whenever I try to output any table, the formatting is very sparse. Ideally the table should be easily fitted in one page width but since the formatting is too sparse, one needs to scroll to the right to see the output.
Here is the code and output.
```{r}
df = data.frame(
first.var = 1:10,
second.var = letters[1:10],
third.var = LETTERS[1:10],
fourth.var = paste0(letters[1:10],"-",LETTERS[1:10]),
fifth.var = "this will not go out of screen",
sixth.var = "but this will go out of the screen"
)
df
```
How can I fit more columns in one page width, so that I don't have to scroll.
Try setting the style (CSS) for the table. I wrapped the table into DT::datatable:
<div style="width = 100%">
```{r}
df = data.frame(
first.var = 1:10,
second.var = letters[1:10],
third.var = LETTERS[1:10],
fourth.var = paste0(letters[1:10],"-",LETTERS[1:10]),
fifth.var = "this will not go out of screen",
sixth.var = "but this will go out of the screen"
)
DT::datatable(df)
```
</div>