modelsummary output to LaTeX with automatic column width and line breaks - latex

I estimate a model with estimatr::lm_robust and display the model output with modelsummary::modelsummary. Consider the following example:
df <- tibble(x=runif(100, 0, 100)) %>% mutate(y=x*(2+runif(100, 0, 10)), z=rep(c(1:10), 10))
tab <- modelsummary::modelsummary(
list("A very, very long title that will span multiple lines"=estimatr::lm_robust(data=df, clusters=z, y~x),
"A short title"=estimatr::lm_robust(data=df, y~x),
"A very, very long title that will span multiple lines"=estimatr::lm_robust(data=df, clusters=z, y~x),
"A short title"=estimatr::lm_robust(data=df, y~x)),
title = "This table should be on one landscape page in LaTeX with automatically adjusted column width and line breaks",
notes = c("A note that is very long and says many things and will span multiple lines where I would like automatic line breaks in LaTeX"),
output="kableExtra")
I now want to perform some kableExtra manipulations:
tab %>%
add_header_above(c(" " = 1, "M1" = 1, "M2" = 1, "M3" = 2)) %>%
row_spec(3, color = 'red') %>%
row_spec(5, background = 'lightblue') %>%
column_spec(1, width="10.5cm")
I want to ensure that the table overall has the full page width (be it landscape or portrait) and line breaks automatically included. How do I best do this?
Further, I want save to .tex. However, tab %>% ... %>% save_kable(format = "latex", file = "latex_table.tex") gives an empty file. What am I doing wrong?
Can someone point me into the right direction?
Thanks a lot.

Related

knitr xtable with long head note too long, stretch out the entire table

I'm new to knitr and Latex stuff, so this may be a very naive question, but I failed to find a correct answer.
I'm doing empirical research that sometimes, we need to add headnotes as instruction for a complex table.
Below is the code I'm currently using (in a file named test.Rnw).
\documentclass[12pt,a4paper]{article}
\usepackage[T1]{fontenc}
\usepackage[utf8]{inputenc}
\usepackage{authblk}
\usepackage{float}
\usepackage{array}
\usepackage{booktabs}
\usepackage{mathptmx}
\usepackage{pdflscape}
\usepackage{fullpage}
\usepackage{cite}
\usepackage{color}
% packages intend to rotate table
\usepackage[graphicx]{realboxes}
\usepackage{adjustbox}
\usepackage{rotating}
\usepackage[top = 0.5in, bottom = 0.5in, left = 0.5in, right = 0.5in]{geometry}
\begin{document}
\section{TEST CODE}
<<Table_Test Test Table, echo=FALSE, results="asis", warning=FALSE, message=FALSE>>=
set.seed(138744)
df_1 <- data.frame("id" = c('a', 'a', 'a', 'b','b','b'),
'time' = c(1991,1991,1991, 2001,2003,2004),
'value' = c('x', 'y','x','z','w','u'))
table_instruction <-"This is only here to test whether the text is too long. This is only here to test whether the text is too long"
print(xtable(df_1,# first zero "represents" row numbers which we skip later
# align and put a vertical line (first "l" again represents column of row numbers)
align = paste0("ll", paste0(rep("c", dim(df_1)[2]-1), collapse = "")),
caption = "Test Table",
label='test-tab'),
floating = TRUE,
size="\\fontsize{8pt}{10pt}\\selectfont", #Change size; useful for bigger tables "normalsize" "footnotesize"
include.rownames = FALSE, #Don't print rownames
include.colnames = TRUE, #We create them ourselves
caption.placement = "top", #"top", NULL
hline.after=NULL, #We don't need hline; we use booktabs
# floating.environment = 'sidewaystable',# to rotate the table
# whether \begin{Table} should be created (TRUE) or not (FALSE)
sanitize.text.function = force, # Important to treat content of first column as latex function
add.to.row = list(pos = list(-1, -1, 0, nrow(df_1)),
command = c(paste0("\\toprule \n"),# NEW row
paste0("\\multicolumn{", dim(df_1)[2],"}{#{}l}{", table_instruction,"} \\\\" ,
"\\cmidrule(l){1-", dim(df_1)[2], "}"),
paste0("\\cmidrule(l){1-", dim(df_1)[2], "} \n"),
paste0("\\bottomrule \n \\multicolumn{",dim(df_1)[2],"}{l}",
"",paste("{\\scriptsize{", "***$p$< .001, **$p$< .01, *$p$< .05","}}",sep = " "),"\\\\"))
)
)
#
\end{document}
Then I render the above code using the code below:
rm(list=ls())
library("knitr")
knit2pdf('test.Rnw')
It works successfully, the problem is that the headnotes (right above the header row) is not self-contained to the table's width. Instead, it stretches the table way too wide.
Any suggestion on how to make the long headnotes, no matter how long, to have consistent width with the table?

How to align text in center using jspdf

How to align text center using jsPDF.
var doc = new jsPDF();
doc.text(40, 250, 'Hi How are you');
If you are using the latest version (1.1.135) the api has changed some for the text function. It now reads as:
API.text = function(text, x, y, flags, angle, align);
If you don't need to use the flags or angle though, you can simply use:
var doc = new jsPDF();
doc.text('Hi How are you', 40, 250, 'center');
Keep in mind that the center call uses the x parameter now as the center of the text string, and not the left most border as it does when rendering left aligned.
Link to source
Edit:
Alternately you can calculate the proper x offset to just use the text function normally like so:
var text = "Hi How are you",
xOffset = (doc.internal.pageSize.width / 2) - (doc.getStringUnitWidth(text) * doc.internal.getFontSize() / 2);
doc.text(text, xOffset, 250);
Angular 6.
Footer align to horizontally center
var doc = new jsPDF();
var pageHeight = doc.internal.pageSize.height || doc.internal.pageSize.getHeight();
var pageWidth = doc.internal.pageSize.width || doc.internal.pageSize.getWidth();
// FOOTER
let str = "Your footer text";
doc.setTextColor(100);
doc.setFontSize(10);
doc.text(str, pageWidth / 2, pageHeight - 10, {align: 'center'});
doc.save("example.pdf");
Above answers didn't work for me, I ended up doing the following to center the text
let textX = (doc.internal.pageSize.getWidth() - doc.getTextWidth(text))/2
doc.text(text, textX, textY);
this worked:
var xOffset = doc.internal.pageSize.width / 2
doc.text('hello world', xOffset, 8, {align: 'center'});
2022: this works assuming your page width is 210 (default A4).
doc.text("This is centred text.", 105, 80, null, null, "center");
Here's a link to their live demo per the README:
http://raw.githack.com/MrRio/jsPDF/master/index.html
2022: I'm finding that JSPDF is buggy. It took a while to figure out how to install the advertised 'runs in a browser' implementation for a PHP app instead of a JS front end framework. There's a line that's required window.jsPDF = window.jspdf.jsPDF; that isn't mentioned anywhere in the documentation, I had to go through a downloaded example piece by piece to find it. Now I'm finding that the center text function doesn't work. In 2 different local environments and a JSFiddle, on multiple browsers, it sends the text off the left side of the page when the align:center option is implemented. While the above solution works, it breaks down if text is longer than one line, which, incidentally, is another out of the box bug - the text runs out of the document instead of wrapping, and there is no wrap option. So, it seems after all these hours I'm out of luck and I'll have to go a different route. Plugin is not maintained and this should be noted in documentation. Recommend to not waste your time.
This works somewhat, but isn't precise, if you know please tell me why.
I calculate the width of my text in order to center it myself.
For this, I used the getTextDimensions() method on my jsPDF object
var pdf = new jsPDF({
orientation : 'p',
unit: 'px',
format: [500, 750],
putOnlyUsedFonts:true
});
var textDimensions = pdf.getTextDimensions('MyText');
You can now use textDimensions.w to get text-width and textDimensions.h for height
Then use this to center your text.
var textWidth = textDimensions.w;
pdf.text('MyText', (pdfWidth / 2) - (textWidth / 2), 100);
BUT: You need to know your PDF's width to do this.
I 'solved' this by defining height and width myself, but you can easily find height and width of common formats online.
Like A4: 210mm*297mm.
Just remember to set unit: 'mm' when creating your jsPDF.
var doc = new jsPDF();
// set midPage for variable use
var midPage = doc.internal.pageSize.getWidth()/2
// Default is 210 mm so default midway by value is 105
doc.setFontSize(40);
doc.text("Octonyan loves jsPDF", 105, 15, null, null, "center");
// Better to use a variable "midPage" (from above)
doc.setFontSize(30);
doc.text("Centered (USA), Centred (UK)", midPage , 30, null, null, "center");

UITableView blank space not working?

so I was trying to align the text in UITableView using.
cell.textLabel?.text = sometext
I have two part in sometext first part is words, second part is number, such as "apple 45" "pear 23", "banana 34"so when they are showing in tableview cell, I want the left side of the words align with each other and the left side the number align with each other. and I can not post a picture here.
so according to the first part word length I added some blank space in the string by appending
let appStr = String(count: 22-cnt, repeatedValue: ( " " as Character))
print("append string is" + appStr + "end")
nameHere = name + appStr + number
I printed out to console in the program and it works fine, but when showing in the simulator it is not aligned.
Don't attempt to align numbers using spaces. Set the label's attributedText, not its text, and use the fact that an NSAttributedString can have tab stops to perform the alignment.

How can I obtain 2 blocks of 3 columns on the same page with TFPDF

I want to create a layout of 2 blocks on a page, each with 3 columns. I am currently using example 10 of the documentation and the setEqualColumns() method.
How can I fix a maximum height?
The result I want to achieve:
you must use SetAutoPageBreak() and resetColumns() functions (more details here). Be careful, if your text is longer than the allowed space, the rest of the text will be written on the next page.
For example :
//Set the distance from the bottom the first block must stop : 130
$pdf->SetAutoPageBreak(true, 130);
//Write the first block : 3 columns, width 50
$pdf->setEqualColumns(3, 50);
$pdf->writeHTML($content_1);
//reset columns
$pdf->resetColumns();
//reset the X position and the page break
$margins = $pdf->getMargins();
$pdf->setX($margins['left']);
$pdf->SetAutoPageBreak(true, $margins['bottom']);
//write the chapter title (like in the TCPDF example 10)
$pdf->SetFillColor(200, 220, 255);
$pdf->Cell(180, 6, 'Chapter 2', 0, 1, '', 1);
//write the second block
$pdf->setEqualColumns(3, 50);
$pdf->writeHTML($content_2);

on_touch_down problems with dynamic created widgets in kivy

I'm new to kivy and need some assistance with the following problem. I adding numbers/operators as widgets (labels) dynamically and at a random position to a layout(FloatLayout). The idea is that when I clicked on a number/operator it will draw a circle around the number/operator. I get some very strange behaviour. Does not matter what number/operator I click the selection circle is only drawn around the last added label. Then to confuse me even more the other number/operator is circled if I press on some random point on the screen
following is the core of my code:
class SelectedObject(Label):
selected = BooleanProperty()
refresh = BooleanProperty()
def __init__(self, **kwargs):
super(SelectedObject, self).__init__(**kwargs)
self.center_x = randint(0, Window.width/2)
self.center_y = randint(0, Window.height/2)
self.bind( refresh = self.redraw )
def redraw(self, *args):
#print('Redraw for: ' + self)
self.canvas.after.clear()
if self.selected:
with self.canvas.after:
Line(circle=(self.center_x, self.center_y, 20))
self.canvas.ask_update()
def on_touch_down(self, touch):
print("touch#: " + str(touch))
if not self.collide_point(touch.x, touch.y):
return False
print("yip: " + self)
self.selected = not self.selected
self.refresh = not self.refresh # force a redraw
return True
class GameNumber(SelectedObject):
pass
class Operator(SelectedObject):
pass
class GameApp(App):
numberArr = ListProperty([])
operatorArr = ListProperty([])
def build(self):
f = FloatLayout()
#populate numberArr and operatorArr
self.buildLevel()
for number in self.numberArr:
numberItem = GameNumber(text = str(number))
f.add_widget(numberItem)
for operator in self.operatorArr:
f.add_widget(Operator(text = operator))
return f
The problem here is that you have not set sizes to the labels. So each label takes up as much space as it can and the last label being on top, it gets the circle.
You need to pass each GameNumber and Operator some sort of size_hint and/or size. For example, if you want each label to be 10 by 10, you can do something like this: numberItem = GameNumber(text=str(number), size_hint=(None, None), size=(10, 10)). You can set their size relative to the window size by for example setting size_hint=(0.1, 0.1).
Remember that size_hint is always (1, 1) by default, so you need to change it something else if you want your widgets to be smaller than the space of the container and set size_hint=(None, None) if you want to set a fixed size yourself.
If you want to position the labels randomly around the screen, take a look at pos_hint, which is more convenient than playing with the size of the window directly. Also, remember that there's a chance that multiple labels might get on top of each other or at the very borders of the window or even outside if you are not careful.
EDIT: To help you find the source of these kind of problems (that usually relate to layout issues), take a look at Kivy Widget Area Display

Resources