如何在word文档的一行中打印两个表

时间:2016-02-10 12:36:17

标签: r ms-word knitr r-markdown

如何将两个R矩阵作为两个表打印到word文档但是在一行(并排)?

示例代码

```{r}
library(knitr)
a <- matrix(c(1,2,3,4,5,6),nrow=3, ncol=2)
rownames(a) <- c("A", "B", "C")
colnames(a) <- c("C1", "C2")
b <- matrix(c(1,2,3,4),nrow=2, ncol=2)
rownames(b) <- c("A", "B")
colnames(b) <- c("C2", "C3")
kable(a)
kable(b)

# Or CL.'s example
dat <- data.frame(LETTERS[1:8], 1:8)
dat2 <- data.frame(LETTERS[1:10], 1:10)
kable(a)
kable(b)
```

1 个答案:

答案 0 :(得分:1)

这是一个hacky解决方案,而不是一个干净的解决方案,但它可能仍然有用。请注意,我推荐这个用于HTML输出(在这种情况下,有更好的解决方案),但仅作为Word输出的解决方法。

问题是,markdown → pandoc → Word链不允许对最终输出进行太多控制。模板可能是摆脱这种限制的一种方法,但在这个答案中我只是使用一个简单的技巧:不是并排打印两个表,而是打印一个包含所有数据的大表。两个“子表”由可变宽度的空列分隔。

(在发布之前10秒我意识到标题下面的水平线可能会被拆分。我不知道如何实现这一点。)

为了尽可能地保持knitr::kable的便利性,我使用kable的输出作为输入并将两个表合并在一起。在一个表的行数多于另一个表的情况下,这有点棘手。然后需要用空单元填充较短的表。这需要在“文本级别”(即kable返回的原始markdown)上完成。通过在将NA行添加到kable之前添加NA行来调整输入数据的长度将导致输出中显示PrintSideBySide <- function(kabled1, kabled2, spaces = 1, fillerChar = "&nbsp;") { # Generate string of protected spaces. filler = paste(rep(fillerChar, times = spaces), collapse = "") # Add empty rows to "shorter" in order to get equal number of rows. expandShorter <- function(shorter, longer) { toAdd <- length(longer) - length(shorter) extraRows <- gsub(pattern = "[^\\|]", replacement = " ", x = shorter[1]) return(c(shorter, rep(extraRows, times = toAdd))) } if (length(kabled1) < length(kabled2)) { kabled1 <- expandShorter(kabled1, kabled2) } else { kabled2 <- expandShorter(kabled2, kabled1) # If length is equal, expandShorter doesn't modify kabled2. } # Print, row by row. for (i in seq_along(kabled1)) { cat(kabled1[i]) # Print row i of first table. cat(" ") if (i != 2) { cat(filler) # Print whitespace in row i. } else { cat(paste(rep("-", times = nchar(filler)), collapse = "")) # In the second row, print a separator between header and body. } cat(" ") cat(kabled2[i]) # Print row i of second table cat("\n") } }

library(knitr)
dat <- data.frame(LETTERS[1:8], 1:8)
dat2 <- data.frame(LETTERS[1:10], 1:10)
PrintSideBySide(kable(dat), kable(dat2), spaces = 5)

  # |LETTERS.1.8. | X1.8| &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; |LETTERS.1.10. | X1.10|
  # |:------------|----:| ------------------------------ |:-------------|-----:|
  # |A            |    1| &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; |A             |     1|
  # |B            |    2| &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; |B             |     2|
  # |C            |    3| &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; |C             |     3|
  # |D            |    4| &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; |D             |     4|
  # |E            |    5| &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; |E             |     5|
  # |F            |    6| &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; |F             |     6|
  # |G            |    7| &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; |G             |     7|
  # |H            |    8| &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; |H             |     8|
  # |             |     | &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; |I             |     9|
  # |             |     | &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; |J             |    10|

使用的一个例子是:

kable

请注意PrintSideBySide有意在align之外调用。这样就可以根据需要设置row.namescaption这样的争论。但是,请注意设置results,否则会破坏表格。

PrintSideBySide PrintSideBySide必须打印asis

下面是一个可重复的例子。请从上面插入--- title: "Print Tables Side By Side" output: word_document --- ```{r, echo = FALSE, results = "asis"} library(knitr) dat <- data.frame(LETTERS[1:8], 1:8) dat2 <- data.frame(LETTERS[1:10], 1:10) PrintSideBySide <- function(kabled1, kabled2, spaces = 1, fillerChar = "&nbsp;") { ## Insert function definition here ## } PrintSideBySide(kable(dat), kable(dat2), spaces = 80) ``` 的定义。

{{1}}

Output