hughjonesd / huxtable

An R package to create styled tables in multiple output formats, with a friendly, modern interface.
http://hughjonesd.github.io/huxtable
Other
321 stars 28 forks source link

Respect line breaks in cells (when escape_contents is TRUE) #154

Closed GitHunter0 closed 4 years ago

GitHunter0 commented 4 years ago
library(huxtable)
lm1 <- lm(mpg ~ cyl, mtcars)
lm2 <- lm(mpg ~ cyl + hp, mtcars)
glm1 <- glm(I(mpg > 20) ~ cyl, mtcars, family = binomial)

huxreg(lm1, lm2, glm1, error_format="({std.error})
                                                            [{p.value}]")

Following the glue package logic, it should be a line break between ({std.error}) and [{p.value}], however they are placed one beside the other in the Rmarkdown PDF/HTML output file.

For example, it displays: (Intercept) 37.885 *** (2.074) [0.000]

When it should be: (Intercept) 37.885 *** (2.074) [0.000]

The weird thing is that in the Console the table is displayed correctly.

Moreover, if I may, can you add in the manual an explanation/example on how to pass results from e.g. lmtest::coeftest() into huxreg (as the manual says it is possible)?

Thank you for very much in advance. Huxtable is an awesome package, the best I found.

hughjonesd commented 4 years ago

The issue here is that line breaks within cells are not automatically translated. Indeed, doing so in LaTeX is intrinsically difficult. (Take a look at this hot mess:

https://tex.stackexchange.com/questions/2441/how-to-add-a-forced-line-break-inside-a-table-cell

)

Possibly that is a worthwhile feature in itself. Meanwhile a workaround might be:


h <- huxreg(lm1, lm2, glm1, error_format="({std.error})\\newline[{p.value}]") 
h <- set_escape_contents(h, error_rows, error_cols, FALSE)
h <- set_wrap(h, error_rows, error_cols, TRUE)
width(h) <- 0.5 # or whatever

or replace \\newline`` by
` in HTML.

GitHunter0 commented 4 years ago

@hughjonesd , it is indeed difficult. The solution workaround with \\newline in PDF output or <br> in HTML does not work either, it appears literally in the cell table , e.g. (2.074)\newline[0.000]

Shouldn't glue::glue() have a specific command for line breaks? Would it solve the problem?

Thanks a lot for the reply.

hughjonesd commented 4 years ago

Could you try the latest github? Don't set escape_contents = FALSE, just do your existing code with the newline included. It should automatically put breaks in.

Glue doesn't deal with HTML/TeX output.

GitHunter0 commented 4 years ago

@hughjonesd , I tried the latest github version but the issue persists, below my minimum working example code:

library(huxtable)
lm1 <- lm(mpg ~ cyl, mtcars)
huxreg(lm1, error_format="({std.error})\\newline[{p.value}]")
> sessionInfo()
R version 3.6.1 (2019-07-05)
Platform: x86_64-w64-mingw32/x64 (64-bit)
Running under: Windows 10 x64 (build 18363)

Matrix products: default

locale:
[1] LC_COLLATE=English_United States.1252 
[2] LC_CTYPE=English_United States.1252   
[3] LC_MONETARY=English_United States.1252
[4] LC_NUMERIC=C                          
[5] LC_TIME=English_United States.1252    

attached base packages:
[1] stats     graphics  grDevices utils     datasets  methods  
[7] base     

other attached packages:
[1] huxtable_4.7.1.9000

loaded via a namespace (and not attached):
 [1] Rcpp_1.0.4.6       compiler_3.6.1     pillar_1.4.4      
 [4] forcats_0.5.0      tools_3.6.1        digest_0.6.25     
 [7] packrat_0.5.0      evaluate_0.14      lattice_0.20-38   
[10] nlme_3.1-140       lubridate_1.7.8    lifecycle_0.2.0   
[13] tibble_3.0.1       checkmate_2.0.0    htmlTable_1.13.3  
[16] pkgconfig_2.0.3    rlang_0.4.6        rstudioapi_0.11   
[19] yaml_2.2.1         haven_2.2.0        xfun_0.13         
[22] stringr_1.4.0      dplyr_0.8.5        knitr_1.28        
[25] hms_0.5.3          generics_0.0.2     htmlwidgets_1.5.1 
[28] vctrs_0.3.0        grid_3.6.1         tidyselect_1.0.0  
[31] glue_1.4.1         data.table_1.12.8  R6_2.4.1          
[34] bookdown_0.18      rmarkdown_2.1      foreign_0.8-71    
[37] pacman_0.5.1       tidyr_1.0.3        purrr_0.3.4       
[40] magrittr_1.5       backports_1.1.6    scales_1.1.1      
[43] matrixStats_0.56.0 htmltools_0.4.0    ellipsis_0.3.1    
[46] expss_0.10.2       labelled_2.3.1     assertthat_0.2.1  
[49] colorspace_1.4-1   stringi_1.4.6      munsell_0.5.0     
[52] broom_0.5.6        crayon_1.3.4 
hughjonesd commented 4 years ago

Sorry, I meant, don't include \\newline but just include an actual newline, like your original example. (You can also do that with \n.)

hughjonesd commented 4 years ago

You will also need to set table width to a specific value.

GitHunter0 commented 4 years ago

@hughjonesd , using \n or an actual newline did not work too in PDF, however in HTML it worked, the only issue is that it got misaligned like this:

(Intercept) 37.885 ***
                    (2.074)
                [0.000]

The alignment is another complicated issue, right? I will try some workarounds.

Thank you very much for the feedback.

hughjonesd commented 4 years ago

Mmm, yes I think escape_contents + newlines + align = "." is going to be messy. I don't think it would be a good idea for me to try and fix this - the code would just get too ugly and complex. So, if you use newlines and escape them, you're on your own with alignment.

I'm more worried about the failure in PDF. Can you post a MWE? Thanks very much. Here's an example that does work for me, using github master. What does it output for you?

library(huxtable)
library(magrittr)
hux("Line 1\nLine 2") %>% set_width(.5) %>% quick_pdf()
GitHunter0 commented 4 years ago

@hughjonesd , yes, it is interesting, your example works. But this MWE does not (there is no line break):

library(huxtable)
library(magrittr)

lm1 <- lm(mpg ~ cyl, mtcars)
lm2 <- lm(mpg ~ cyl + hp, mtcars)

huxtable::huxreg(lm1, lm2,
  error_format="({std.error}) \n [{statistic}] \n p={p.value}") %>% 
  quick_pdf()

Regarding the alignment, I found a simple solution to make all tables prettier without unexpected misalignments: Force center alignment with this %>% huxtable::set_align('center')

My suggestion is to make that as the default because it would avoid a lot of headache for those just starting to use huxtable and still don't know how to customize the layout very well, as was my case.

Thank you again.

hughjonesd commented 4 years ago

But it works if you add ...%>% set_width(0.5) %>% ....

I don't think center alignment by default is likely to work for many cases. I have rarely had cause to use it, in particular if I have text in cells. Great if it works for you, though.

GitHunter0 commented 4 years ago

@ hughjonesd , I didn't know the set_width() trick, it helps a lot. We just have to try different widths for each case, right? In the example above, if I use set_width(0.5), the stars appear on the line below (line break). The footnote may suffer the same issue. In this very particular case the best alignment I got was using this setting:

library(huxtable)
library(magrittr)

lm1 <- lm(mpg ~ cyl, mtcars)
lm2 <- lm(mpg ~ cyl + hp, mtcars)

huxtable::huxreg(lm1, lm2,
  error_format="({std.error}) \n [{statistic}] \n p={p.value}") %>%
  set_width(0.53) %>% 
  set_align('center') %>% 
  quick_pdf()

Regarding the center alignment, probably it is working for me because I am not using text in cells so far, but I will be aware it may cause issues too.

Thanks again for the explanations, they have been very helpful.