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

时间:2018-03-12 17:22:23

标签: r r-markdown bookdown

如果我希望以kabley +- error形式进行衡量及其错误,那么获得好表(例如y(error))的最佳方法是什么?具有通常的错误规则:错误中有1个有效数字,值中的数字位数相同,依此类推。例如:

  • 1.124 \ pm 0.003
  • 0.30 \ pm 0.02

等等。

可重复的示例

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及其Deltas,我会得到不同的“宽度”,并且我希望在小数点后得到相同的位数。

1 个答案:

答案 0 :(得分:2)

这是tidyverse对你的问题的看法,这可能是非常冗长的。一些解释:

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

2)第二个mutate()块围绕&#34;正常&#34; xy列的长度与Delta列的长度相同。 - 2L根据..列中Delta本身之前的数字,避免错误舍入。

3)第三个mutate()块首先处理两个&#34;异常&#34;情况:第一个if_else()处理舍入的y数字没有.和数字,但Delta.y值的情况。第二个if_else()负责处理舍入流程中的最后一位数为0R舍入为四舍五入的情况。对x列重复这两个度量。

4)第四个mutate()块会在xy列的值末尾添加空格,以确保错误编号对齐。

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

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)
}