How to take borders off table in R markdown - r

Below is my code that I am using to manually create a table. When I knit in R markdown, there is a border about it and ## in front of each row. Is there a way to remove these items? Or would I be best creating data frames using these data points and then using gt?
library(dplyr)
comparison <- matrix(c(-2267,-345916,-185344,-44.4,-24.0,-57.1,"+1224","+191534","+80,347","51.4","55.4","43.4"),ncol=3,byrow=TRUE)
colnames(comparison) <- c("Daycare Services","Total, All Industries","Accommodation and Food Services")
rownames(comparison) <- c("Decline","% Decline","Recovery","% Recovery")
comparison <- as.table(comparison)
comparison
Here is how I create it. Create a new R markdown file. Next, I put the code chunk in the first chunk (look below) and then enter the word, "comparison" in the place of summary(cars) below in the section that appears as such
knitr::opts_chunk$set(echo = TRUE)
comparison <- matrix(c(-2267,-345916,-185344,-44.4,-24.0,-57.1,"+1224","+191534","+80,347","51.4","55.4","43.4"),ncol=3,byrow=TRUE)
colnames(comparison) <- c("Daycare Services","Total, All Industries","Accommodation and Food Services")
rownames(comparison) <- c("Decline","% Decline","Recovery","% Recovery")
comparison <- as.table(comparison)
comparison
summary(cars)

If we are using gt, then we do
```{r}
library(gt)
library(dplyr)
comparison <- matrix(c(-2267,-345916,-185344,-44.4,-24.0,-57.1,"+1224","+191534","+80,347","51.4","55.4","43.4"),ncol=3,byrow=TRUE)
colnames(comparison) <- c("Daycare Services","Total, All Industries","Accommodation and Food Services")
rownames(comparison) <- c("Decline","% Decline","Recovery","% Recovery")
out <- as.data.frame(comparison)
gt(out, rownames_to_stub = TRUE)
```
-output

Related

Convert list of different length into data table for markdown for html format

This is what Im doing to generate a markdown so that all the things should be in one place.
How can i put these output into a datatable form which are more readable and easier to search.The list which is made are of different length. Each list has a series of table under it.
If there a way to convert these differing length list to data table format that would be really helpful
The table looks like this
## Prepare for analyses
```{r,warning=FALSE,message=FALSE}
set.seed(1234)
library(europepmc)
library(tidypmc)
library(tidyverse)
#library(dplyr)
```
```{r setup, include=FALSE}
knitr::opts_chunk$set(echo = FALSE)
```
##Cytarabine cytogenetically normal aml adult clinical trial Randomized Controlled Trial. 828 records found, showing 10
```{r,include=FALSE}
b <-epmc_search(query = 'cytarabine cytogenetically normal aml adult clinical trial Randomized Controlled Trial OPEN_ACCESS:Y',limit = 10)
pmcids <- b$pmcid[b$isOpenAccess=="Y"]
docs <- map(pmcids, epmc_ftxt)
my_tables <- map(docs, pmc_table)
```
```{r}
names(my_tables) <- pmcids
```
The code chunk input and output is then displayed as follows:
```{r basicconsole}
source("flat.R")
L1 <- flattenlist(my_tables)
l.f <- Filter(function(a) any(!is.na(a)), L1)
l.f
#tibble:::print.tbl_df(head(df))
#n <- paste0("Valporic_", names(l.f), ".txt")
for (i in 1:length(l.f)) {
write.table(l.f[i], sep = "\t",row.names = FALSE,col.names = TRUE,file=paste0(names(l.f)[i], ".txt"))
}
UPDATE
I have manged to covert those tibble into dataframe
using this solution
##Outout
```{r}
abc <- mapply(cbind, l.f)
abc
But when it is rendered in the markdown the column formatting is gone. Now i have now dataframe inside list.
But still im not sure how to put that into a data table
**UPDATE 2.0 **
The better approach is to read those saved output as list of files into data table and then use it as markdown but so far it is taking only one ID only. My code.
tbl_fread <-
list.files(pattern = "*.txt") %>%
map_df(~fread(.))
knitr::kable(head(tbl_fread), "pipe")
Is it possible to put these files as such.
if a list of file are from one PMCID then those would be all in one column such as if PMCID one has 3 output then all of them should be one the same row. Then the next PMCID in the second one etc etc.
UPDATE new
I have managed to align the output into more readable format. But It seems that by default all the files assigned to multiple columns which would be the case given that im reading all the files together since my idea of using the list to data table didn't work.
If i can push or stack each unique PMCID over one another instead of all in one after another that would be. Good
knitr::kable(tbl_fread, align = "lccrr")
This may be something you can adapt for R Markdown. I'm not sure what the rationale is to save and load the tables. Instead, you could obtain the tables and show in html directly.
As you are using HTML, make sure to have results='asis' in your chunk. You can use a for loop and seq_along to show each table. You can include information in your table caption, such as the PMCID as well as table number.
---
title: "test13121"
author: "Ben"
date: "1/31/2021"
output: html_document
---
```{r setup, include=FALSE}
knitr::opts_chunk$set(echo = TRUE)
```
# Libraries
```{r}
library(tidypmc)
library(tidyverse)
library(europepmc)
library(kableExtra)
```
# Get Articles
```{r, echo = FALSE}
b <-epmc_search(query = 'cytarabine aml OPEN_ACCESS:Y',limit = 6)
pmcids <- b$pmcid[b$isOpenAccess=="Y"]
docs <- map(pmcids, epmc_ftxt)
my_tables <- map(docs, pmc_table)
names(my_tables) <- pmcids
```
# Show Tables
```{r, echo=F, results='asis'}
for (i in seq_along(my_tables)) {
for (j in seq_along(my_tables[[i]])) {
print(kable(x = my_tables[[i]][[j]], caption = paste0(names(my_tables)[i], ": Table ", j)))
}
}
```

Is it possible to use crosstalk with kableextra table?

I've formatted my table nicely using kableextra and I want to apply a crosstalk filter_slider to one of the columns so that the user can adjust it. However, I am getting the following error:
Error in if (nrow(df) > 0) as.character(1:nrow(df)) else character() : argument is of length zero
The code works fine if the table is not formatted using kableextra. How can I fix this? Here is some basic reproducible code I put together to demonstrate:
Name <- c("Dwyer, Andy","Ludgate, April", "Knope, Leslie")
Rank <- c(1,2,3)
Hours <- c(1000,2000,5000)
Title <- c("Shoe Shine","Intern","Deputy Director")
df <- data.frame(Name,Rank,Title, Hours)
library(crosstalk)
df2 <- SharedData$new(df)
filter_slider("Rank","Top",df2,column=~Rank)
library(kableExtra)
df3 <- kable(df,row.names=FALSE) %>%
kable_styling(bootstrap_options = c("striped","hover",full_width=T),fixed_thead = T)%>%row_spec(seq(1,nrow(df),2),background = "aliceblue")
df3
df4 <- SharedData$new(df3)
filter_slider("Rank","Top",df4,column=~Rank)
I expect the filter_slider to work on both tables without error. I need an interactive filter to work on the kable formatted table and cannot use shiny.

wrapping wide table in rmarkdown

I have a really wide table (300+ columns) and would like to display it by wrapping the columns. In the example I will just use 100 columns.
What I have in mind is repetitively using kable to display the subset of the table:
library(kableExtra)
set.seed(1)
data = data.frame(matrix(rnorm(300, 10, 1), ncol = 100))
kable(data[, 1:5], 'latex', booktabs = T)
kable(data[, 6:10], 'latex', booktabs = T)
kable(data[, 11:15], 'latex', booktabs = T)
But this is apparently tedious... I know there are scaling down options but since I have so many columns, it won't be possible.
Is there any parameter I can twist in kable to make it happen?
Updated:
#jay.sf 's answer seems working well, but it didn't yield the same result here. Instead I got some plain code - could you please have a second look and let me know where can I improve? Thanks!
my sessionInfo() is: R version 3.5.1 (2018-07-02) with rmarkdown::pandoc_version() of 1.19.2.1.
This question is actually trickier than I thought at first glance. I used some tidyverse functions, specifically dplyr::select to get columns and purrr::map to move along groups of column indices.
My thinking with this was to make a list of vectors of column indices to choose, such that the first list item is 1:20, the second is 21:40, and so on, in order to break the data into 20 tables of 5 columns each (the number you use can be a different factor of ncol(data)). I underestimated the work to do that, but got ideas from an old SO post to rep the numbers 1 to 20 along the number of columns, sort it, and use that as the grouping then to split the columns.
Then each of those vectors becomes the column indices in select. The resulting list of data frames each gets passed to knitr::kable and kableExtra::kable_styling. Leaving things off there would get map's default of printing names as well, which isn't ideal, so I added a call to purrr::walk to print them neatly.
Note also that making the kable'd tables this way meant putting results="asis" in the chunk options.
---
title: "knitr chunked"
output: pdf_document
---
```{r include=FALSE}
library(knitr)
library(kableExtra)
library(dplyr)
library(purrr)
set.seed(1)
data = data.frame(matrix(rnorm(300, 10, 1), ncol = 100))
```
```{r results='asis'}
split(1:ncol(data), sort(rep_len(1:20, ncol(data)))) %>%
map(~select(data, .)) %>%
map(kable, booktabs = T) %>%
map(kable_styling) %>%
walk(print)
```
Top of the PDF output:
You could use a matrix containing your columns numbers and give it into a for loop with the cat function inside.
---
output: pdf_document
---
```{r, results="asis", echo=FALSE}
library(kableExtra)
set.seed(1)
dat <- data.frame(matrix(rnorm(300, 10, 1), ncol=100))
m <- matrix(1:ncol(dat), 5)
for (i in 1:ncol(m)) {
cat(kable(dat[, m[, i]], 'latex', booktabs=TRUE), "\\newline")
}
```
Result

rstudio hangs and aborts with rmarkdown loop

I have several datasets each of which have a common grouping factor. I want to produce one large report with separate sections for each grouping factor. Therefore I want to re-run a set of rmarkdown code for each iteration of the grouping factor.
Using the following approach from here doesnt work for me. i.e.:
---
title: "Untitled"
author: "Author"
output: html_document
---
```{r, results='asis'}
for (i in 1:2){
cat('\n')
cat("#This is a heading for ", i, "\n")
hist(cars[,i])
cat('\n')
}
```
Because the markdown I want to run on each grouping factor does not easily fit within one code chunk. The report must be ordered by grouping factor and I want to be able to come in and out of code chunks for each iteration over grouping factor.
So I went for calling an Rmd. with render using a loop from an Rscript for each grouping factor as found here:
# run a markdown file to summarise each one.
for(each_group in the_groups){
render("/Users/path/xx.Rmd",
output_format = "pdf_document",
output_file = paste0(each_group,"_report_", Sys.Date(),".pdf"),
output_dir = "/Users/path/folder")
}
My plan was to then combine the individual reports with pdftk. However, when I get to the about the 5th iteration my Rstudio session hangs and eventually aborts with a fatal error. I have ran individually the Rmd. for the grouping factors it stops at which work fine.
I tested some looping with the following simple test files:
.R
# load packages
library(knitr)
library(markdown)
library(rmarkdown)
# use first 5 rows of mtcars as example data
mtcars <- mtcars[1:5,]
# for each type of car in the data create a report
# these reports are saved in output_dir with the name specified by output_file
for (car in rep(unique(rownames(mtcars)), 100)){
# for pdf reports
rmarkdown::render(input = "/Users/xx/Desktop/2.Rmd",
output_format = "pdf_document",
output_file = paste("test_report_", car, Sys.Date(), ".pdf", sep=''),
output_dir = "/Users/xx/Desktop")
}
.Rmd
```{r, include = FALSE}
# packages
library(knitr)
library(markdown)
library(rmarkdown)
library(tidyr)
library(dplyr)
library(ggplot2)
```
```{r}
# limit data to car name that is currently specified by the loop
cars <- mtcars[rownames(mtcars)==car,]
# create example data for each car
x <- sample(1:10, 1)
cars <- do.call("rbind", replicate(x, cars, simplify = FALSE))
# create hypotheical lat and lon for each row in cars
cars$lat <- sapply(rownames(cars), function(x) round(runif(1, 30, 46), 3))
cars$lon <- sapply(rownames(cars), function(x) round(runif(1, -115, -80),3))
cars
```
Today is `r Sys.Date()`.
```{r}
# data table of cars sold
table <- xtable(cars[,c(1:2, 12:13)])
print(table, type="latex", comment = FALSE)
```
This works fine. So I also looked at memory pressure while running my actual loop over the Rmd. which gets very high.
Is there a way to reduce memory when looping over a render call to an Rmd. file?
Is there a better way to create a report for multiple grouping factors than looping over a render call to an Rmd. file, which doesn't rely on the entire loop being inside one code chunk?
Found a solution here rmarkdown::render() in a loop - cannot allocate vector of size
knitr::knit_meta(class=NULL, clean = TRUE)
use this line before the render line and it seems to work
I am dealing with the same issue now and it's very perplexing. I tried to create some simple MWEs but they loop successfully on occasion. So far, I've tried
Checking the garbage collection between iterations of rmarkdown::render. (They don't reveal any special accumulations.)
Removing all inessential objects
Deleting any cached files manually
Here is my question:
How can we debug hangs? Should we set up special log files to understand what's going wrong?

Column alignment with kableExtra using group_rows

I'm using Rmarkdown to produce a PDF of frequency tables. Producing a complex frequency table after running freq from questionr and adding row groupings with group_rows leads to an alignment problem on the last line of the first group. Reproducible example here:
---
output:
pdf_document:
latex_engine: xelatex
fig_caption: true
---
```{r}
library(haven)
library(questionr)
library(dplyr)
library(magrittr)
library(knitr)
library(kableExtra)
# Build some data
x <- rep(c(1,0),times=50)
y <- c(rep(1,times=25),rep(0,times=75))
z <- c(rep(1,times=75),rep(0,times=25))
# Function to run frequencies on several variables at a time
MassFreq <- function(...){
step1 <- list(...) # Wrap items into a list
step2 <- lapply(step1,freq,total=TRUE) # run frequencies on all items
step3 <- bind_rows(step2) # collapse list results into single df
Response <- unlist(lapply(step2,row.names),recursive=FALSE) # Get row names from frequencies
step4 <- cbind(Response,step3) #Stick row names at front of the dataframe
}
# Run function - returns a data frame object
test <- MassFreq(x,y,z)
# Build table
test %>%
kable(format="latex", booktabs = TRUE, row.names=FALSE) %>%
group_rows("Group 1",1,3) %>%
group_rows("Group 2",4,6) %>%
group_rows("Group 3",7,9)
```
Gives me this upon knitting:
The first "Total" text is right-aligned, but everything else is fine. Adding align=('lrrr') in the kable line does nothing, and align=('crrr') is kind of a mess. Using the index method for group_rows produces the same results. When leaving out the group_rows commands, everything in the first column is left-aligned and looks fine. My hunch is that kableExtra isn't playing well with questionr because the "Total" rows are created when running questionr::freq.
This is a bug in current CRAN version of kableExtra, 0.5.2. It has been fixed in the dev version. I will make a CRAN release next week.

Resources