RMarkdown表中的科学格式、下标和上标(docx输出)

xt0899hw  于 2023-04-18  发布在  其他
关注(0)|答案(4)|浏览(173)

假设我有以下rmd:

---
title: "Table won't work"
author: "Exhausted student"
date: "2022/01/28"
output: 
  bookdown::word_document2
---

```{r table, echo=F, warning=F, message=F}
library(tidyverse)
a <- tibble(
  constants = c("c", "NA", "h", "e", "H2O"),
  values = c(2.998e8, 6.022e23, 6.626e-34, -1.602e-19, 18.02)
)

knitr::kable(a, digits = 35)

其产生[this table in Word](https://i.stack.imgur.com/4YC5L.png)。

### 问题

我需要科学格式使用上标和乘号(即2.998 × 108),有些单元格需要下标(例如NA和H2O)。
[The final table should look like this](https://i.stack.imgur.com/ewdcD.png).我怎么能这样做?

### What I've tried/would never try

1.**`huxtable`包及其[`markdown()`](https://hughjonesd.github.io/huxtable/reference/markdown.html)功能**:我设法将一些内容格式化为`H~2~O`,然后通过`huxtable(a) %>% `markdown<-`(TRUE)`在表中启用markdown。这不能识别语法,显然不会在可预见的未来工作,根据作者。
1.**`flextable`和[`as_sub()`](https://davidgohel.github.io/flextable/reference/as_sub.html)**:生成正确的格式。我将标签传递给`flextable::compose()`,其中的标签类似于`as_paragraph(list_values = list("H", as_sub("2"), "O")`。另外,我必须**操作单元格一个接一个**。技术上仍然可行,但我确实有100多个单元格需要格式化的表格。
1.**先输出,后Word格式**:同样,需要一个接一个的操作。如果它能自动解决所有问题,那将是一个选择。
1.说服学校官僚接受**html/pdf/latex作为输出**:这永远是不可能的选择。
1.格式化外部单词,然后**将格式化的表格导出为图像**:在报告中被严格禁止。

**编辑:**表格现在可以工作了!非常感谢[Maël's answer](https://stackoverflow.com/a/70891533/13511545),但请检查[my own findings](https://stackoverflow.com/a/70894001/13511545)以查看我的最终结果:

![](https://i.stack.imgur.com/BKKVK.png)
ohfgkhjo

ohfgkhjo1#

您可以使用波浪号(~)来放置下标,使用插入符号(^)来放置上标;然后使用sprintf来获得预期的数字格式:

---
title: "Table won't work"
author: "Exhausted student"
date: "2022/01/28"
output: 
  bookdown::word_document2
---

```{r table, echo=F, warning=F, message=F}
library(tidyverse)

expSup <- function(x, digits=3) {
  sprintf(paste0("%05.", digits, "f x 10^%d^"), x/10^floor(log10(abs(x))), floor(log10(abs(x))))
}

a <- tibble(
  constants = c("c", "N~A~", "h", "e", "H~2~0"),
  values = expSup(c(2.998e8, 6.022e-23, 6.626e-34, -1.602e-19, 18.02))
)

knitr::kable(a)

![](https://i.stack.imgur.com/mnpjw.png)
zf2sa74q

zf2sa74q2#

对于此open issue,一个选项可能福尔斯禁区:
1.创建html文档
1.为下标插入html标记
1.打开html文件(不是查看器)

  1. ctrl+c,然后在你的word文件中ctrl+v。
---
output: html_document
---

```{r table, echo=F, warning=F, message=F}
library(tidyverse)
library(gt)
a <- tibble(
    constants = c("c", "N<sub>A</sub>", "h","e","H<sub>2</sub>O"),
    values = c(2.998e8, 6.022e23, 6.626e-34, -1.602e-19, 18.02)
)
a %>%
  mutate(constants = map(constants, html)) %>%
  gt() %>%
  fmt_scientific(values)
xeufq47z

xeufq47z3#

Maël's answer中的expSup()函数将科学格式转换为markdown格式。对于我的脚本,我稍微修改了一下函数:

exp_sup <- function(x, digits = 3) {
  sprintf(paste0("%05.", digits, "f $\\times$ 10^%d^"), x / 10^floor(log10(abs(x))), floor(log10(abs(x))))
}

我将"f x 10^%d^"更改为"f $\\times$ 10^%d^",以便显示正确的乘法符号(×)。

使用flextable

这种格式在Kable中运行良好。但是,我的大部分工作流需要flextable来制作标题/交叉引用/出版样式/等等。不幸的是,尽管expSup函数自动将科学符号格式化为markdown,但它不能使markdown语法在flextable中运行。
然而,ftExtra::colformat_md()可以。因此,通过将修改后的exp_sup()函数与ftExtra组合,我最终能够生成一个学术外观的表:

下面是我最终输出的代码;如果您也试图制作可重复的学术报告与大量的表格在Word格式,希望这有帮助!

---
title: "The tables work!"
author: "Satisfied Student"
date: "2022/01/28"
output: 
  bookdown::word_document2:
    reference_docx: styleRef.docx
---
```{r setup, include = F}
library(easypackages)
packages(
  "tidyverse",
  "flextable", # This works best for my workflow
  "ftExtra", # For markdown formatting work in flextable
  "officer" # You can customize appearance/format/etc. of caption *prefixes*
)

knitr::opts_chunk$set(
  warning = FALSE,
  message = FALSE,
  echo = FALSE,

  # Make the table caption format definable in reference_docx styles
  tab.cap.style = "Table Caption",

  # Make "Table 1:" prefixes not bold
  tab.cap.fp_text = fp_text_lite(bold = FALSE)

  # The tab.cap settings MUST be in a separate chunk from tables
)

# Converts scientific format to markdown
exp_sup <- function(x, digits = 3) {
  sprintf(paste0("%05.", digits, "f $\\times$ 10^%d^"), x / 10^floor(log10(abs(x))), floor(log10(abs(x))))
}
# The $\\times$ makes proper multiply symbols
a <- tibble(
  constants = c("c", "N~A~", "h", "e", "H~2~O"),
  values = c(2.998e8, 6.022e23, 6.626e-34, -1.602e-19, 18.02)
)

a %>%
  mutate(values = exp_sup(values)) %>%
  flextable() %>%
  set_caption(
    caption = "(ref:foo)", # Produces formatted caption text
    style = "Table Caption"
  ) %>%
  colformat_md() %>% # Subscript/superscript works in flextable now!
  theme_booktabs() %>% # The 3-part-table used in academics
  align(align = "center", part = "all") %>% #Align everything to center
  set_table_properties(layout = "autofit") # Comfortable width/height every cell

(ref:foo) A scientifically formatted flextable with ^superscripts^ and ~subscripts~


## 更新:在表标题中使用markdown

以前我使用文本引用(例如`(ref:foo)`)在表格标题中使用markdown格式。现在似乎无法正确渲染。(截至2023年4月。不知道是哪个包导致的)
要解决这个问题,您可以将markdown标题写为字符串,然后将其传递给`set_caption()`中的`ftExtra::as_paragraph_md()`。例如:

tab_caption <- "A scientifically formatted flextable with ^superscripts^ and ~subscripts~"

a %>%
flextable() %>%
set_caption(
caption = ftExtra::as_paragraph_md(tab_caption), # <- Here
style = "Table Caption"
) %>%
colformat_md() %>%
theme_apa() %>% # The 3-part-table used in academics
align(align = "center", part = "all") %>%
set_table_properties(layout = "autofit")

tf7tbtn2

tf7tbtn24#

您的代码应如下所示:

{r table, echo=F, warning=F, message=F}
library(tidyverse)
a <- tibble(
constants = c("c", "NA", "h", "e", "$H_2O$"),
values = c("$2.998 * {10^{8}}$", "$6.022 * {10^{-23}}$", "$6.626 * {10^{-34}}$", "$-1.602 * {10 ^{-19}}$", "$1.802 * {10^{1}}$")
)

knitr::kable(format = "html", a, digits = 35)

它会给予你这样的输出:

相关问题