简体   繁体   English

使用markdown,rstudio和knitr对齐表格中的图像

[英]Alignment of images in tables with markdown, rstudio and knitr

I'm trying to create a standard monthly report for work in PDF format using Rstudio and I want to incorporate ggplot output with a table of figures - a new chart, one per cell on each row. 我正在尝试使用Rstudio为PDF格式的工作创建标准的月度报告,并且我想将ggplot输出与数字表格合并在一起-一个新的图表,每行每个单元格一个。 I'm new to markdown, latex, pandoc and knitr so this is a bit of minefield for me. 我是Markdown,乳胶,Pandoc和Knitr的新手,所以对我来说这是个雷区。

I have found out how to insert the charts using kable but the images are not aligned with the text on the same row. 我发现了如何使用kable插入图表,但是图像与同一行上的文本不对齐。

I've put some (rstudio markdown) code using dummy data at the bottom of my question, and here are some images showing what I'm trying to do and the problem I've got 我在问题的底部放了一些使用伪数据的代码(rstudio markdown),下面是一些图像,它们显示了我正在尝试做的事情和遇到的问题

Example of graphic I want to incorporate into table 我想合并到表格中的图形示例

This is what the table looks like with the misaligned text and images 这是表格的文本和图像未对齐的样子

You can see that the text and the images are not aligned. 您会看到文本和图像未对齐。 If I leave the images out the tables are nice and compact, putting the images in means the tables spread out over multiple pages, even though the images themselves aren't that tall. 如果我将图像放在外面的话,桌子就好又紧凑,将图像放进去就意味着桌子分散在多页上,即使图像本身并不高。

Any advice welcome - code snippets doubly so. 任何建议的欢迎-代码段加倍。

Many thanks 非常感谢


  title: "Untitled"
  output: pdf_document
  ---

  This example highlights the issue I'm having with formatting a nice table with the graphics and the vertical alignment of text.



  ```{r echo=FALSE, results='hide', warning=FALSE, message=FALSE}
    ## Load modules
    library(dplyr)
    library(tidyr)
    library(ggplot2)

    ## Create a local function to plot the z score
    varianceChart <- function(df, personNumber) {
      plot <- df %>%
        filter(n == personNumber) %>%
        ggplot() +
        aes(x=zscore, y=0) +
        geom_rect(aes(xmin=-3.32, xmax=-1.96, ymin=-1, ymax=1), fill="orange2", alpha=0.8) + 
        geom_rect(aes(xmin=1.96, xmax=3.32, ymin=-1, ymax=1), fill="olivedrab3", alpha=0.8) +
        geom_rect(aes(xmin=min(-4, zscore), xmax=-3.32, ymin=-1, ymax=1), fill="orangered3") + 
        geom_rect(aes(xmin=3.32, xmax=max(4, zscore), ymin=-1, ymax=1), fill="chartreuse4") +
        theme(axis.title = element_blank(), 
              axis.ticks = element_blank(), 
              axis.text = element_blank(),
              panel.grid.minor = element_blank(),
              panel.grid.major = element_blank()) +
        geom_vline(xintercept=0, colour="black", alpha=0.3) +
        geom_point(size=15, shape=4, fill="lightblue") ##Cross looks better than diamond

      return(plot)
    }

    ## Create dummy data
    Person1 <- rnorm(1, mean=10, sd=2) 
    Person2 <- rnorm(1, mean=10, sd=2)
    Person3 <- rnorm(1, mean=10, sd=2)
    Person4 <- rnorm(1, mean=10, sd=2) 
    Person5 <- rnorm(1, mean=10, sd=2) 
    Person6 <- rnorm(1, mean=6,  sd=1) 

    ## Add to data frame
    df <- data.frame(Person1, Person2, Person3, Person4, Person5, Person6)

    ## Bring all samples into one column and then calculate stats
    df2 <- df %>% 
      gather(key=Person, value=time)

    mean <- mean(df2$time)
    sd   <- sqrt(var(df2$time))

    stats <- df2 %>%
      mutate(n = row_number()) %>%
      group_by(Person) %>%
      mutate(zscore = (time - mean) / sd)

    graph_directory <- getwd() #'./Graphs'

    ## Now to cycle through each Person and create a graph
    for(i in seq(1, nrow(stats))) {
      print(i)
      varianceChart(stats, i)

      ggsave(sprintf("%s/%s.png", graph_directory, i), plot=last_plot(), units="mm", width=50, height=10, dpi=1200)
    }

    ## add a markup reference to this dataframe
    stats$varianceChart <- sprintf('![](%s/%s.png)', graph_directory, stats$n)  

    df.table <- stats[, c(1,2,5)]
    colnames(df.table) <- c("Person Name", "Time taken", "Variance Chart")
  ```


  ```{r}  
    library(knitr)
    kable(df.table[, c(1,2)], caption="Rows look neat and a sensible distance apart")
    kable(df.table, caption="Rows are separated a long way apart and images and text are misaligned")

  ```

Consider using LaTeX: 考虑使用LaTeX:

在此处输入图片说明

Note the line with \\\\includegraphics . 注意带有\\\\includegraphics的行。 You could also try the (commented out) line adjusting the plot margin. 您也可以尝试(注释掉)线来调整绘图边距。

\documentclass{article}
\usepackage{graphicx}

\begin{document}

  This example highlights the issue I'm having with formatting a nice table with the graphics and the vertical alignment of text.



<<preamble, echo=FALSE, results='hide', warning=FALSE, message=FALSE>>=
## Load modules
library(dplyr)
library(tidyr)
library(ggplot2)

## Create a local function to plot the z score
varianceChart <- function(df, personNumber) {
  plot <- df %>%
    filter(n == personNumber) %>%
    ggplot() +
    aes(x=zscore, y=0) +
    geom_rect(aes(xmin=-3.32, xmax=-1.96, ymin=-1, ymax=1), fill="orange2", alpha=0.8) + 
    geom_rect(aes(xmin=1.96, xmax=3.32, ymin=-1, ymax=1), fill="olivedrab3", alpha=0.8) +
    geom_rect(aes(xmin=min(-4, zscore), xmax=-3.32, ymin=-1, ymax=1), fill="orangered3") + 
    geom_rect(aes(xmin=3.32, xmax=max(4, zscore), ymin=-1, ymax=1), fill="chartreuse4") +
    theme(axis.title = element_blank(), 
          axis.ticks = element_blank(), 
          axis.text = element_blank(),
          panel.grid.minor = element_blank(),
          panel.grid.major = element_blank() 
          #,plot.margin = margin(0, 0, 0, 0, "lines")
    ) +
    geom_vline(xintercept=0, colour="black", alpha=0.3) +
    geom_point(size=15, shape=4, fill="lightblue") ##Cross looks better than diamond

  return(plot)
}

## Create dummy data
Person1 <- rnorm(1, mean=10, sd=2) 
Person2 <- rnorm(1, mean=10, sd=2)
Person3 <- rnorm(1, mean=10, sd=2)
Person4 <- rnorm(1, mean=10, sd=2) 
Person5 <- rnorm(1, mean=10, sd=2) 
Person6 <- rnorm(1, mean=6,  sd=1) 

## Add to data frame
df <- data.frame(Person1, Person2, Person3, Person4, Person5, Person6)

## Bring all samples into one column and then calculate stats
df2 <- df %>% 
  gather(key=Person, value=time)

mean <- mean(df2$time)
sd   <- sqrt(var(df2$time))

stats <- df2 %>%
  mutate(n = row_number()) %>%
  group_by(Person) %>%
  mutate(zscore = (time - mean) / sd)

graph_directory <- getwd() #'./Graphs'

## Now to cycle through each Person and create a graph
for(i in seq(1, nrow(stats))) {
  print(i)
  varianceChart(stats, i)

  ggsave(sprintf("%s/%s.pdf", graph_directory, i), plot=last_plot(), units="mm", width=50, height=10, dpi=1200)
}

## add a markup reference to this dataframe
stats$varianceChart <- sprintf('\\begin{tabular}{l}\\relax \\includegraphics{%s/%s.pdf} \\end{tabular}', graph_directory, stats$n)  

df.table <- stats[, c(1,2,5)]
colnames(df.table) <- c("Person Name", "Time taken", "Variance Chart")
@


<<tables, results='asis'>>= 
library(knitr)
library(xtable)
print.xtable(xtable(df.table[, c(1,2)], caption="Rows look neat and a sensible distance apart"), sanitize.text.function = function(x){x})
print.xtable(xtable(df.table, caption="Rows are separated a long way apart and images and text are misaligned"), sanitize.text.function = function(x){x})
@

\end{document}

Or you make use of \\raisebox . 或者您使用\\raisebox It puts the content inside of a new box and with its parameters you can modify the offset of the box (play around with the parameter currently set to -0.4 ): 它将内容放入新框内,并使用其参数可以修改框的偏移量(使用当前设置为-0.4的参数进行播放):

---
title: "Untitled"
output: pdf_document
---

This example highlights the issue I am having with formatting a nice table with the graphics and the vertical alignment of text.

```{r echo=FALSE, results='hide', warning=FALSE, message=FALSE}
## Load modules
library(dplyr)
library(tidyr)
library(ggplot2)

## Create a local function to plot the z score
varianceChart <- function(df, personNumber) {
  plot <- df %>%
             filter(n == personNumber) %>%
             ggplot() +
             aes(x=zscore, y=0) +
             geom_rect(aes(xmin=-3.32, xmax=-1.96, ymin=-1, ymax=1), fill="orange2", alpha=0.8) + 
             geom_rect(aes(xmin=1.96, xmax=3.32, ymin=-1, ymax=1), fill="olivedrab3", alpha=0.8) +
             geom_rect(aes(xmin=min(-4, zscore), xmax=-3.32, ymin=-1, ymax=1), fill="orangered3") + 
             geom_rect(aes(xmin=3.32, xmax=max(4, zscore), ymin=-1, ymax=1), fill="chartreuse4") +
             theme(axis.title = element_blank(), 
                   axis.ticks = element_blank(), 
                   axis.text = element_blank(),
                   panel.grid.minor = element_blank(),
                   panel.grid.major = element_blank()) +
                   geom_vline(xintercept=0, colour="black", alpha=0.3) +
                   geom_point(size=15, shape=4, fill="lightblue") ##Cross looks better than diamond
  return(plot)
}

## Create dummy data
Person1 <- rnorm(1, mean=10, sd=2) 
Person2 <- rnorm(1, mean=10, sd=2)
Person3 <- rnorm(1, mean=10, sd=2)
Person4 <- rnorm(1, mean=10, sd=2) 
Person5 <- rnorm(1, mean=10, sd=2) 
Person6 <- rnorm(1, mean=6,  sd=1) 

## Add to data frame
df <- data.frame(Person1, Person2, Person3, Person4, Person5, Person6)

## Bring all samples into one column and then calculate stats
df2  <- df %>% gather(key=Person, value=time)
mean <- mean(df2$time)
sd   <- sqrt(var(df2$time))

stats <- df2 %>%
             mutate(n = row_number()) %>%
             group_by(Person) %>%
             mutate(zscore = (time - mean) / sd)

graph_directory <- getwd() #'./Graphs'

## Now to cycle through each Person and create a graph
for(i in seq(1, nrow(stats))) {
  print(i)
  varianceChart(stats, i)

  ggsave(sprintf("%s/%s.png", graph_directory, i), plot=last_plot(), units="mm", width=100, height=20, dpi=1200)
}

## add a markup reference to this dataframe
stats$varianceChart <- sprintf('\\raisebox{-.4\\totalheight}{\\includegraphics[width=0.2\\textwidth, height=20mm]{%s/%s.png}}', graph_directory, stats$n) 

df.table <- stats[, c(1,2,5)]
colnames(df.table) <- c("Person Name", "Time taken", "Variance Chart")
```

```{r}
library(knitr)
kable(df.table[, c(1,2)], caption="Rows look neat and a sensible distance apart")
kable(df.table, caption="Rows are separated a long way apart and images and text are misaligned")
```

在此处输入图片说明

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM