科学测量 +- Rmarkdown/bookdown 表中的错误

scientific measurements +- error in Rmarkdown/bookdown tables

如果我想以 y +- errory +- errory(error),具有通常的错误规则:有 1 位有效数字错误,相同位数的值,等等。例如:

等等。

可重现的例子

df<-data.frame(
  x=runif(5),
  Delta.x=runif(5)/10,
  y=runif(5),
  Delta.y=runif(5)/7
)
df.print<-with(df, data.frame(
  x=paste0(x, "(", Delta.x, ")"),
  y=paste0(y, "(", Delta.y, ")")
))

kable(df.print)

如果我使用 format(x, digits=3) x、y 和它们的增量,我会得到不同的 "widths",我想得到相同的小数点后位数。

这里 tidyverse 解决您的问题,可以说它非常冗长。一些解释:

1) 第一个 mutate() 块舍入两个 Delta 列以具有一个有效数字并将其转换为字符;这保留了长度。

2) 第二个 mutate() 块舍入 "normal" xy 列,使其与 Delta 列的长度相同。 - 2L 避免基于 . 之前的数字和 Delta 列中的 . 本身的错误舍入。

3)第三个mutate()块首先处理两种"unusual"情况:第一个if_else()处理四舍五入的y数字没有的情况. 和数字,但 Delta.y 值有。第二个 if_else() 处理舍入过程中最后一位数字是 0 的情况,R 在舍入中下降。 x 列重复这两项措施。

4) 第四个 mutate() 块在 xy 列的值末尾添加白色 space 以确保错误编号对齐.

5) 最后的 unite()mutate() 命令合并列并为第二个数字添加括号。

library("tidyverse")
library("knitr")

df %>% 
  mutate(Delta.x = signif(Delta.x, digits = 1L), 
         Delta.x = as.character(Delta.x), 
         Delta.y = signif(Delta.y, digits = 1L), 
         Delta.y = as.character(Delta.y)) %>% 
  mutate(x = round(x, digits = str_count(Delta.x) - 2L), 
         x = as.character(x),
         y = round(y, digits = str_count(Delta.y) - 2L), 
         y = as.character(y)) %>% 
  mutate(y = if_else(condition = str_count(y, "\.") == 0, 
                     true = str_c(y, str_dup("0", str_count(Delta.y) - str_count(y) - 1L), sep = "."),
                     false = y),
         y = if_else(condition = str_count(Delta.y) - str_count(y) != 0,
                     true = str_c(y, str_dup("0", times = str_count(Delta.y) - str_count(y))),
                     false = y),
         x = if_else(condition = str_count(x, "\.") == 0, 
                     true = str_c(x, str_dup("0", str_count(Delta.x) - str_count(x) - 1L), sep = "."),
                     false = x),
         x = if_else(condition = str_count(Delta.x) - str_count(x) != 0,
                     true = str_c(x, str_dup("0", times = str_count(Delta.x) - str_count(x))),
                     false = x)) %>% 
  mutate(x = if_else(condition = str_count(x) < max(str_count(x)),
                     true = str_c(x, str_dup(" ", times = max(str_count(x)) - str_count(x))),
                     false = x),
         y = if_else(condition = str_count(y) < max(str_count(y)),
                     true = str_c(y, str_dup(" ", times = max(str_count(y)) - str_count(y))),
                     false = y)) %>%
  unite(x, x, Delta.x, sep = " (") %>% 
  unite(y, y, Delta.y, sep = " (") %>% 
  mutate(x = str_c(x, ")"), 
         y = str_c(y, ")")) %>% 
  kable()


|x           |y             |
|:-----------|:-------------|
|1.0  (0.1)  |0.20  (0.01)  |
|0.12 (0.07) |0.8   (0.1)   |
|0.71 (0.03) |0.18  (0.09)  |
|0.63 (0.02) |0.805 (0.003) |
|0.27 (0.09) |0.106 (0.008) |

此外,您可以设置全局 options(scipen = 999)(或任何其他大数)以避免数字的科学表示,例如2e-5(在你的 kable 的情况下应该看起来像 0.00002)。

编辑:更新并阐明了一些命令。

更新(Javi_VM)

我只是把它变成了一个函数。您可以给出 2 个向量或 1 个 data.frame 两列。它仍然缺乏对科学计数法的支持(例如 1.05 10^9),但可以启动。

scinumber <- function(df=NULL, x, Delta.x){
  if (is.null(df)) {
    df <- data.frame(
      x = x,
      Delta.x = Delta.x
    )
  } else {
    colnames(df)[colnames(df)==x] <- "x"
    colnames(df)[colnames(df)==Delta.x] <- "Delta.x"
  }
  require(tidyverse)
  options(scipen = 999)
  output <- 
    df %>% 
    mutate(Delta.x = signif(Delta.x, digits = 1L), 
           Delta.x = as.character(Delta.x)) %>% 
    mutate(x = round(x, digits = str_count(Delta.x) - 2L), 
           x = as.character(x)
    ) %>% 
    mutate(x = if_else(condition = str_count(x, "\.") == 0, 
                       true = str_c(x, str_dup("0", str_count(Delta.x) - str_count(x) - 1L), sep = "."),
                       false = x),
           x = if_else(condition = str_count(Delta.x) - str_count(x) != 0,
                       true = str_c(x, str_dup("0", times = str_count(Delta.x) - str_count(x))),
                       false = x)) %>% 
    mutate(x = if_else(condition = str_count(x) < max(str_count(x)),
                       true = str_c(x, str_dup(" ", times = max(str_count(x)) - str_count(x))),
                       false = x)) %>%
    unite(x, x, Delta.x, sep = " (") %>% 
    mutate(x = str_c(x, ")"))

  return(output)
}