I have a flextable:
df = data.frame(col1 = c(123,234,54,5), col2 = c(NA,1,2,3), col3 = 5:8)
df %>%
flextable() %>%
footnote(i = 1, j = 1,
value = as_paragraph('this is a footnote'),
ref_symbols = "1",
part = "body") %>%
footnote(i = 1, j = 1,
value = as_paragraph(as_b("Note (2):"),"This is another foonote"),
ref_symbols = "2",
part = "body")
that shows
What I would like to do is keep the flextable and footnotes, but remove the little 1 and 2 that appear in the footer section.
You can use add_footer_lines() to add any content in a new line and append_chunks() to append any content in existing cells/rows/columns (prepend_chunks() can sometimes be useful)
library(flextable)
df <- data.frame(col1 = c(123,234,54,5), col2 = c(NA,1,2,3), col3 = 5:8)
df |>
flextable() |>
add_footer_lines("Here is a foonote") |>
add_footer_lines(as_paragraph(as_b("Note (2):"),"This is another foonote")) |>
append_chunks(i = 1, j = 1, as_sup("12")) |>
append_chunks(i = 2, j = 1, as_sup("‡"))
The David Gohel's previous answer is fine for not getting this behavior of adding the symbol in the cell and in the footnote, but this previous answer will not add "1" or "2" in the cells of the table. In this case, you have to add these symbols by yourself in the cells, since the footnote func' require a "value" parameter (or you get Error in mapply(function(x, y) { : argument "value" is missing, with no default).
In order to add ¹, ², etc. in the cells of the table, I suggest to use a superscript generator (e.g., here), and a paste0 func' to modify the cells and add the symbol ¹ to the data; then use the add_footer_lines func' to create the footnote that you want, without the symbol at the beginning of the footnote (see David Gohel's previous answer).
PS: for a good readability of the "ref_symbols", I prefer to use letters when the symbol appears next to a number (e.g., I use "† ", "‡ ", "A" or "B") and I add number-footnote-symbol when it come next to a text (e.g., ¹ or ²).
I want to add a row explaining the columns of my table. But the add_header_above function is a bit confusing. How do you use it? This is the built-in example:
x = kable(head(mtcars), "html")
# Add a row of header with 3 columns on the top of the table. The column span for the 2nd and 3rd one are 5 & 6.
add_header_above(x, header = c(" ", "Group 1" = 5, "Group 2" = 6))
You have to create a named vector corresponding to the header row you want, e.g. c("Group 1" = 5)
Each header item consists of the text and its "span"
"span" is a single number specifying how many columns the item spans in the header row.
These spans cumulate and have to sum to the total number of column in the table.
So, if you have a 7 column table, and wanted a header spanning the whole table, you could say:
add_header_above(myKe, header = c("Big title" = 7))`
If you wanted an empty header over an initial column of rownames, followed by a header spanning columns 2:3, another spanning 3:4, and the last 2 cells blank in your 7-column table, you would say:
add_header_above(myKe, header = c(" " = 1, "header1" = 2, "header2" = 2, " " = 2))
note: A header can't be blank, so you need to use a white space " " in "blank" cells.
Important Caveat: This construction of c("my header" = 7) won't work if your headers are constructed on the fly because tmp= "X"; c(tmp = 7) is interpreted as c("tmp" = 7)
Instead, you would have to say something like:
header = 7
names(header) = "X"
myKe = add_header_above(myKe, header = header)
I would like to wrap and rotate column HEADER headings in a kable-latex table. I can control the width of the column using column spec, but I need to group columns in my table with a header, and it is the names in the header that I want to rotate and wrap. A very basic example of my table is below.
example <- data.frame(name="testname", score1=3, score2=2, score3=0)
table <- kable(example, format="latex", escape = F) %>%
column_spec(1:4, width = "5em") %>%
add_header_above(c(" " = 1, "Rhyme Product" = 2, "Sound ID Middle" = 1)) %>% add_header_above(c(" " = 1, "Exploring Words" = 2, "Early Skills" = 1), bold = T)
I would like to flip the first set of column groupings (Rhyme Product and Sound ID Middle) on their side (angle = -45) and wrap the text on two separate lines taking up a lot less space. Is this possible?
This one is a pretty simple fix. I'm surprised no one has answered it over the years. One possibility is that the setting did not exist when this question was answered.
To add the line breaks, add a \n to the column names where you would like the breaks to be. To rotate, add angle = "-45" to the add_header_above line you would like to modify. See the code below.
library(tidyverse)
library(kableExtra)
example <- data.frame(name="testname", score1=3, score2=2, score3=0)
table <- kable(example, format="latex", escape = F) %>%
column_spec(1:4, width = "5em") %>%
add_header_above(c(" " = 1, "Rhyme \nProduct" = 2, "Sound ID \nMiddle" = 1), angle = "-45") %>%
add_header_above(c(" " = 1, "Exploring Words" = 2, "Early Skills" = 1), bold = T)
table
Table output
Interestingly enough, the align argument accepts a vector of angles (i.e align = c("-45", "90")) to apply to each column. This is also true for row_spec. I have not seen anyone talking about this, nor is it anywhere in the documentation. It is really useful, however.
So, I have this workflow :
I have selected 2 columns(Day and Temperature) from my file using ‘Columns filter’. And I connected to ‘R plot’ that I configurated but I obtain this :
The day column is not selected as X axis but (Row ID) and the Y axis is ok.
This is my code in R plot:
# Library
library(qcc)
library(readr)
library(Rserve)
Rserve(args = "--vanilla")
# Data column filter from CSV file imported
Test <- kIn
#Background color
qcc.options(bg.margin = "white", bg.figure = "gray95")
#R graph ranges of a continuous process variable
qcc(data = Test,
type = "R",
sizes = 5,
title = "Sample R Chart Title",
digits = 2,
plot = TRUE)
Here is my try (using KNIME's R, not the community contribution):
#install.packages("qcc")
library(qcc)
data <- knime.in
#Change the names to use Day instead of row keys
row.names(data) <- data$Day
#Using the updated data
plot(qcc(data = data,
type = "R",
sizes = 5,
title = "Sample R Chart Title",
digits = 2,
plot = TRUE))
With results like:
If you want to select the column for the X axis, just change the row.names assignment. (It can also come from knime.flow.in in case the column name is coming from a flow variable, but as I understand it is not the case for you.)
I am trying to combine multiple tableGrob objects with a ggplot object into a single .png file; I am having trouble understanding how to edit the tableGrob theme parameters in a way that lets me adjust the padding and dimensions of the table objects. Ideally, I want them to be in a 4*1 grid, with minimal padding between each. The text of the table objects should also be left-justified.
I am working with dummy data, and each row of my input dataset will be used to create its own .png file (two rows are included in the code snippet below to generate a reproducible example).
I tried to use this post as an example, and set the grid.arrange spacing based on the "heights" attributes of each table object, but this hasn't quite done the trick. As a side note, right now, the plot gets overwritten each time; I'll fix this later, am just concerned with getting the output dimensions/arrangement correct. Code is below; edited to include library calls, and fixed a typo:
require("ggplot2")
require("gridExtra")
require("grid")
# Generate dummy data frame
sampleVector <- c("1", "Amazing", "Awesome", "0.99", "0.75", "0.5", "$5,000.00", "0.55", "0.75", "0.31", "0.89", "0.25", "Strong community support", "Strong leadership", "Partners had experience", "", "CBO not supportive", "Limited experience", "Limited monitoring", "")
sampleVectorB <- c("3", "Amazing", "Awesome", "0.99", "0.75", "0.5", "$5,000.00", "0.55", "0.75", "0.31", "0.89", "0.25", "Strong community support", "Strong leadership", "Partners had experience", "", "CBO not supportive", "Limited experience", "Limited monitoring", "")
sampleDF <- data.frame(rbind(sampleVector, sampleVectorB))
colnames(sampleDF) <- c("CBO", "PMQ", "HMQ", "ER", "PR", "HR", "NS", "CTI", "Home and Hosp", "Home", "Phone", "Other", "S1", "S2", "S3", "S4", "C1", "C2", "C3", "C4")
indata <- sampleDF
#Finds the longest string from a vector of strings (i.e. #chars, incld. whitespace); returns index into this vector that corresponds to this string
findMax <- function(tempVector){
tempMaxIndex <- 1
for(i in 1:length(tempVector)){
print(nchar(tempVector[i]))
if(nchar(tempVector[i]) > nchar(tempVector[tempMaxIndex])){
tempMaxIndex <- i
}
}
return(tempMaxIndex)
}
# Same as above but w/o the colon:
addWhitespacePlain <- function(stringVec, maxNum){
for(i in 1:length(stringVec))
{
string <- stringVec[i]
while(nchar(string) < maxNum+1){
string <- paste(string, " ")
}
stringVec[i] <- string
}
return(stringVec)
}
staticText <- c("Participant Match Quality", "Hospital-Level Match Quality", "Enrollment Rate", "Participant Readmissions", "Hospital Readmissions", "Net Savings",
"Strengths", "Challenges")
m <- findMax(staticText)
staticText <- addWhitespacePlain(staticText, nchar(staticText[m]))
# Loop through our input data and keep only one CBO each pass
for(i in 1:length(indata$CBO)){
# Select only the row that has this CBO's data
temp <- indata[i,]
###############################################################################################
# MAKE TOP TEXT TABLE (as a DF)
# Get values from our input data set to fill in the values for the top text portion of the graphic
topVals <- t(data.frame(temp[2], temp[3], temp[4], temp[5], temp[6], temp[7]))
topDF <- data.frame(staticText[1:6], topVals, row.names=NULL)
colnames(topDF) <- c(paste("CBO", temp[1]), " ")
# Find which of the strings from the top text portion is the longest (i.e. max # of chars; including whitespace)
m2 <- findMax(rownames(topDF)) # returns an index into the vector; this index corresponds to string w/max num of chars
# Add whitespace to non-max strings so all have the same length and also include colons
rownames(topDF) <- addWhitespacePlain(rownames(topDF), nchar(rownames(topDF)[m2]))
# for testing
# print(topDF, right=FALSE)
###############################################################################################
# MAKE BAR CHART
#Subset the data to select the vars we need for the horizontal bar plot
graphdata <- t(data.frame(temp[,8:12]))
vars <- c("CTI", "Home & Hosp.", "Home", "Phone", "Other")
graphDF <- data.frame(vars, graphdata, row.names = NULL)
colnames(graphDF) <- c("vars", "values")
# Make the plot (ggplot object)
barGraph <- ggplot(graphDF, aes(x=vars, y=values,fill=factor(vars))) +
geom_bar(stat = "identity") +
theme(axis.title.y=element_blank())+
theme(legend.position="none")+
coord_flip()
# print(barGraph)
###############################################################################################
# MAKE BOTTOM TEXT TABLE
strengths <- t(data.frame(temp[13], temp[14], temp[15], temp[16]))
challenges <- t(data.frame(temp[17], temp[18], temp[19], temp[20]))
#Drop nulls
strengths <- data.frame(strengths[which(!is.na(strengths)),], row.names=NULL)
challenges <- data.frame(challenges[which(!is.na(challenges)),], row.names=NULL)
colnames(strengths) <- c(staticText[7])
colnames(challenges) <- c(staticText[8])
###############################################################################################
# OUTPUT (padding not resolved yet)
# Set the path for the combined image
png("test1", height=1500, width=1000)
#customTheme <- ttheme_minimal(core=list(fg_params=list(hjust=0, x=0.1)),
# rowhead=list(fg_params=list(hjust=0, x=0)))
# top<-tableGrob(topDF, theme=customTheme)
# bottom_strength <- tableGrob(strengths, theme=customTheme)
# bottom_challenges <- tableGrob(challenges, theme=customTheme)
top<-tableGrob(topDF)
bottom_strength <- tableGrob(strengths)
bottom_challenges <- tableGrob(challenges)
x <- sum(top$heights)
y <- sum(bottom_strength$heights)
z <- sum(bottom_challenges$heights)
grid.arrange(top, barGraph, bottom_strength, bottom_challenges,
as.table=TRUE,
heights=c(2, 1, 2, 2),
nrow = 4)
# heights= unit.c(x, unit(1), y, z))
dev.off()
}
Your example is too complicated, I'm not sure what exactly is the issue. The following 4x1 layout has zero padding, is that what you're after?
ta <- tableGrob(iris[1:4,1:2])
tb <- tableGrob(mtcars[1:3,1:3])
tc <- tableGrob(midwest[1:5,1:2])
p <- qplot(1,1) + theme(plot.background=element_rect(colour = "black"))
h <- unit.c(sum(ta$heights), unit(1,"null"), sum(tb$heights), sum(tc$heights))
grid.newpage()
grid.arrange(ta,p,tb,tc, heights=h)