Я пытаюсь использовать пакет flextable
, чтобы получить несколько красиво отформатированных таблиц в моем Rmarkdown (переход к файлу слова). В целом таблицы работают нормально, но если я помещу их в оператор if, если из оператора if будет напечатано что-то еще, я не увижу таблицу. Есть идеи, что происходит?
Обновление от января 2020 г. для всех, кто все еще смотрит на это
Начиная с версии 0.5.5 flextable появилась новая функция docx_value
для решения этой проблемы, я обновил ответ, чтобы отразить это, чтобы другие люди не использовали сложные обходные пути, теперь есть простое решение.
Мой пример (запустить все вместе):
---
title: "Testing"
output:
word_document:
reference_docx: styles.docx
---
```{r setup, include=FALSE}
knitr::opts_chunk$set(echo = TRUE)
```
## R Markdown
```{r defaults}
library(pander)
library(knitr)
library(flextable)
```
1-й тест работает нормально - без оператора if и новых строк по обе стороны от таблицы
## test 1 table no if statemnets
```{r test1, echo = FALSE, results = 'asis'}
test <- data.frame (c = 1:5, x = 6:10)
testft <- flextable(test)
testft
```
2-й тест имеет оператор if без другого текста и работает нормально
## test 2 if statement no other text
```{r test2, echo = FALSE, results = 'asis'}
RunTable <- TRUE
if (RunTable){
testft
}
```
Но если я попытаюсь добавить другие выходные данные в свой оператор if, с новыми разрывами строк или без них, я не получу никакой таблицы в своем выводе.
## test 3 if statement with other text
```{r test3, echo = FALSE, results = 'asis'}
#Hack so dat works up to year 2047 as cpp functions in padr can't handle data beyond 2038
#Get Daily Values
RunTable <- TRUE
if (RunTable){
print("before ")
testft
print("after ")
}
```
## test 4 if statement with other text and newlines
```{r test4, echo = FALSE, results = 'asis'}
RunTable <- TRUE
if (RunTable){
print("if with linebreak before ")
cat(" \n")
knit_print(testft)
cat(" \n")
print("if with linebreak after ")
}
```
Я предполагаю, что ваша проблема связана с Эта проблема. Изменение проблемных фрагментов вроде этого, кажется, работает:
## test 3 if statement with other text
```{r test3, echo = FALSE}
RunTable <- TRUE
if (RunTable){
text <- c(
"before ",
knit_print(testft),
"after "
)
asis_output(paste(text, collapse = "\n"))
}
```
## test 4 if statement with other text and newlines
```{r test4, echo = FALSE}
RunTable <- TRUE
if (RunTable){
text <- c(
"if with linebreak before ",
" \\newline",
knit_print(testft),
" \\newline\n",
"if with linebreak after "
)
asis_output(paste(text, collapse = "\n"))
}
```
По поводу последнего:
\\newline
, чтобы вставить лишнюю пустую строку перед таблицей.\n
для пустой строки после, иначе у меня это не сработало бы.\\newline
, как до, так и после, но одна пустая строка была максимумом, который я мог получить.Да, это странно. Кажется, есть тонкая разница между опцией чанка и функцией asis_output
. Если вы установите results='asis'
и сделаете что-то вроде print("a")
, вы получите необработанный вывод R без форматирования, но не необработанный текст. knit_print
for flextable
использует asis_output
, поэтому другим частям может даже не понадобиться опция results
.
Спасибо, это работает для меня, несмотря на проблему, говорящую, что это работает только на верхнем уровне.
Не уверен, что вы рассмотрите другой пакет, но это, похоже, работает:
---
title: "Testing"
output:
word_document
---
```{r setup, include=FALSE}
knitr::opts_chunk$set(echo = TRUE, fig.height=1.5, fig.width=3, fig.align='right', fig.align = "center")
```
## R Markdown
```{r defaults}
library(pander)
library(knitr)
library(flextable)
library(tableHTML)
```
## test 1 table no if statemnets
```{r test1, echo = FALSE}
test <- data.frame (c = 1:5, x = 6:10)
tab <- tableHTML(test, widths = c(60, 60), rownames = FALSE) %>% add_theme('scientific')
tab %>% tableHTML_to_image()
```
## test 2 if statement no other text
```{r test2, echo = FALSE}
RunTable <- TRUE
if (RunTable){
tab %>% tableHTML_to_image()
}
```
```{r test3, echo = FALSE}
#Hack so dat works up to year 2047 as cpp functions in padr can't handle data beyond 2038
#Get Daily Values
RunTable <- TRUE
if (RunTable){
print("before ")
tab %>% tableHTML_to_image()
print("after ")
}
```
## test 4 if statement with other text and newlines
```{r test4, echo = FALSE}
RunTable <- TRUE
if (RunTable){
print("if with linebreak before ")
cat(" \n")
tab %>% tableHTML_to_image()
cat(" \n")
print("if with linebreak after ")
}
Например, вы можете увидеть тест 4 в качестве вывода:
Пара замечаний:
Привет, спасибо за предложение, но я хочу, чтобы они были отформатированы в виде таблицы в слове (мой автоматический отчет входит в другой отчет кем-то другим, поэтому, если они хотят что-то изменить, было бы хорошо, если бы они могли просто сделать это на месте)
Конечно имеет смысл :)
Вы можете использовать опцию чанка results = 'asis'
и написать содержимое openxml с помощью format
следующим образом:
## test 4 if statement with other text and newlines
```{r test4, echo = FALSE, results = 'asis'}
RunTable <- TRUE
if (RunTable){
print("if with linebreak before ")
cat(" \n")
cat(
paste(
"\n```{=openxml}",
format(testft, type = "docx"),
"```\n", sep = "\n")
)
cat(" \n")
print("if with linebreak after ")
}
```
Обновление от января 2020 г. для всех, кто все еще смотрит на это
Начиная с версии 0.5.5 flextable появилась новая функция docx_value
для решения этой проблемы, как описано в новостях пакета:
docx_value
, позволяющая отображать гибкие таблицы не на верхнем уровне
вызовы внутри документа R Markdown.
Хм, в этой проблеме говорится, что если у вас есть результат опции чанка = 'asis', тогда он должен работать. Поскольку я счастлив иметь этот набор (и он есть в моем примере), это не должно быть проблемой. Так что вопрос остается в силе. У меня еще не было возможности протестировать ваш код, интересно, останется ли проблема, поскольку
asis_output
все еще вызывается в операторе if, и проблема гласит: «asis_output()
работает только в выражениях R верхнего уровня», чего не будет. . Я проверю и посмотрю, возможно ли это обходное решение завтра