使用tidyverse在R中按行格式格式化数字数据表以输出电缆

时间:2018-06-24 23:26:09

标签: r dataframe format tidyverse kable

我有一个要保存为kable()表的值表。表格的每一行都是一个变量,每一列都是该变量的值(例如,平均值,最小值,最大值等)。您可以将format()函数应用于数据框的列,但跨行应用它似乎很尴尬。我终于用这段代码实现了我的目标,但是如果有一种tidier的实现方式,我将很感兴趣!

library(tidyverse)
library(broom)
library(kableExtra)

# test data
all <- tibble(PARAMETER=c("A","B", "C"), 
              Value1=c(0.0123, 1230, NA), 
              Value2=c(0.0234, 2340, 1.23), 
              Units=c("m", "Pa", "ha"), 
              Description=c("Length", "Pressure", "Area"))

# my formatting function
my_format <- function(x){
  y <- format(x, digits=3, scientific=FALSE, TRIM=TRUE)
  y[is.na(x)] <- ""
  y
}

# format values by row
all_formatted <- all %>%
  `row.names<-`(.$PARAMETER) %>% # set row names for transpose
  select(-PARAMETER, -Units, -Description) %>% # only numeric columns
  t() %>% # transpose
  tidy() %>% # convert to tibble (creates .rownames column)
  modify(my_format) %>% # apply format function to each column of values in place
  `row.names<-`(.$.rownames) %>% # set row names for transpose
  select(-.rownames) %>% # drop rownames column
  t() %>% # transpose
  tidy() %>% # convert to tibble (creates .rownames column)
  select(-.rownames) %>% # drop rownames
  add_column(PARAMETER=all$PARAMETER, .before=1) %>% # add back nonnumeric columns
  add_column(UNITS=all$Units, 
             DESCRIPTION=all$Description)

# print formatted table
all_formatted %>%
  kable() %>%
  kable_styling(
    bootstrap_options = c("condensed", "striped", "hover"),
    full_width=FALSE, position="left", font_size=12) %>%
  save_kable(file="temp.html", self_contained=TRUE) # very slow

enter image description here

1 个答案:

答案 0 :(得分:0)

不确定您对kable的重视程度,但是flextable是我最喜欢的东西之一,它通常以相同的方式呈现到HTML和.doc。诀窍是按列而不是按行...仅指定要以不同格式设置的数字的特征:

library(flextable)
all %>% regulartable() %>% align(align="center",part="all") %>% 
    set_formatter(Value1 = function(x) 
                     ifelse(x > 1, sprintf("%.0f", x), sprintf("%.03f", x) ),
                  Value2 = function(x) 
                     ifelse(x > 1, sprintf("%.0f", x), sprintf("%.03f", x) ))

enter image description here

希望这会有所帮助:)