How can I format sessionInfo() in rmarkdown?

后端 未结 2 572
广开言路
广开言路 2021-02-08 12:46

If I want to nicely print my sessionInfo in R for a PDF, I can just use

toLatex(sessionInfo())

It seems like there should be a similar option f

2条回答
  •  暖寄归人
    2021-02-08 13:14

    Another solution making use of devtools::session_info() which can be copied straight into an R markdown file (Rmd):

    R environment

    
    (ref:Reproducibility-SessionInfo-R-environment-title) R environment session info for reproducibility of results
    
    \renewcommand{\arraystretch}{0.8} 
    ```{r Reproducibility-SessionInfo-R-environment, echo=FALSE, message=FALSE, warning=FALSE, fig.align="center", out.width='100%', results='asis'}
    library("devtools")
    # library("knitr")
    
    df_session_platform <- devtools::session_info()$platform %>% 
      unlist(.) %>% 
      as.data.frame(.) %>% 
      rownames_to_column(.)
    
    colnames(df_session_platform) <- c("Setting", "Value")
    
    kable(
      df_session_platform, 
      booktabs = T, 
      align = "l",
      caption = "(ref:Reproducibility-SessionInfo-R-environment-title)", # complete caption for main document
      caption.short = " " # "(ref:Reproducibility-SessionInfo-R-environment-caption)" # short caption for LoT
    ) %>% 
      kable_styling(full_width = F,
                    latex_options = c(
                      "hold_position" # stop table floating
                    ) 
      ) 
    ```
    \renewcommand{\arraystretch}{1} 
    

    Required Packages

    
    (ref:Reproducibility-SessionInfo-R-packages-title) Package info for reproducibility of results
    
    \renewcommand{\arraystretch}{0.6} 
    ```{r Reproducibility-SessionInfo-R-packages, echo=FALSE, message=FALSE, warning=FALSE, fig.align="center", out.width='100%', results='asis'}
    df_session_packages <- devtools::session_info()$packages %>% 
      as.data.frame(.) %>% 
      filter(attached == TRUE) %>% 
      dplyr::select(loadedversion, date) %>% 
      rownames_to_column
    
    colnames(df_session_packages) <- c("Package", "Loaded version", "Date")
    
    kable(
      df_session_packages, 
      booktabs = T, 
      align = "l",
      caption = "(ref:Reproducibility-SessionInfo-R-packages-title)", # complete caption for main document
      caption.short = " " # "(ref:Reproducibility-SessionInfo-R-packages-caption)" # short caption for LoT
    ) %>% 
      kable_styling(full_width = F,
                    latex_options = c(
                      "hold_position" # stop table floating
                    ) 
      ) 
    ```
    \renewcommand{\arraystretch}{1} 
    

    If one has loaded very many packages, one can split the table into several columns

    credits go to @user2554330 and @RobertoScotti for their snippets to split tables provided to this SO Q.

    ```{r prepare multicolumn-table, echo=FALSE, message=FALSE, warning=FALSE}
    colnames(df_session_packages) <- c("Package", "Loaded version", "Date")
    
    rows <- seq_len(nrow(df_session_packages) %/% 2)
    l_session_packages <- list(df_session_packages[rows,1:3],  
               matrix(numeric(), nrow=0, ncol=1),
               df_session_packages[-rows, 1:3])
    ```
    
    Generate the table: for few packages vertically crunched on a portrait page
    \renewcommand{\arraystretch}{0.8} 
    ```{r Reproducibility-SessionInfo-R-packages, echo=FALSE, message=FALSE, warning=FALSE, fig.align="center", out.width='100%', results='asis'}
    kable(
      l_session_packages, 
      row.names = T,
      booktabs = T, 
      align = "l",
      caption = table_caption, # complete caption for main document
      caption.short = table_caption_title # short caption for LoT
    ) 
    ```
    \renewcommand{\arraystretch}{1} 
    
    Generate the table: for very many packages on a landscape page
    \begin{landscape}
    ```{r Reproducibility-SessionInfo-R-packages-lanscape, echo=FALSE, message=FALSE, warning=FALSE, fig.align="center", out.width='100%', results='asis'}
    kable(
      l_session_packages, 
      row.names = T,
      booktabs = T, 
      align = "l",
      caption = table_caption, # complete caption for main document
      caption.short = table_caption_title # short caption for LoT
    ) 
    ```
    \end{landscape}
    
    Generate the table: for very many packages on a landscape page
    \begin{landscape}
    ```{r Reproducibility-SessionInfo-R-MANY-packages-lanscape, echo=FALSE, message=FALSE, warning=FALSE, fig.align="center", out.width='100%', results='asis'}
    # SOURCE: Roberto Scotti (StackOverflow)
    # https://stackoverflow.com/questions/56445149/how-can-i-split-a-table-so-that-it-appears-side-by-side-in-r-markdown
    
    split.print <- function(x, cols = 2, sects = 1, spaces = 1, caption = "", label = ""){
      if (cols < 1) stop("cols must be GT 1!")
      if (sects < 1) stop("sects must be GT 1!")
      rims <- nrow(x) %% sects
      nris <- (rep(nrow(x) %/% sects, sects) + c(rep(1, rims), rep(0, sects-rims))) %>%
        cumsum() %>%
        c(0, .)
    
      for(s in 1:sects){
        xs <- x[(nris[s]+1):nris[s+1], ]
        rimc <- nrow(xs) %% cols
        nric <- (rep(nrow(xs) %/% cols, cols) + c(rep(1, rimc), rep(0, cols-rimc))) %>%
          cumsum() %>%
          c(0, .)
        lst <- NULL
        spc <- NULL
        for(sp in 1:spaces) spc <- c(spc, list(matrix(numeric(), nrow=0, ncol=1)))
        for(c in 1:cols){
          lst <- c(lst, list(xs[(nric[c]+1):nric[c+1], ]))
          if (cols > 1 & c < cols) lst <- c(lst, spc)
        }
        kable(lst,
              row.names = T,
              caption = ifelse(sects == 1, caption, paste0(caption, " (", s, "/", sects, ")")),
              #label = "tables", format = "latex",
              booktabs = TRUE) %>%
          kable_styling(latex_options = "hold_position") %>%
          print()
      }
    }
    
    df_session_packages %>%
      dplyr::select(1:3) %>%
      split.print(cols = 2, sects = 1, caption = "multi page table")
    ```
    \end{landscape}
    

提交回复
热议问题