【问题标题】:Format numeric data table rowwise in R using tidyverse for kable output使用 tidyverse 在 R 中按行格式化数字数据表以进行 kable 输出
【发布时间】:2018-06-24 23:26:09
【问题描述】:

我有一个要保存为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

【问题讨论】:

标签: r dataframe format tidyverse kable


【解决方案1】:

不确定您对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) ))

希望这会有所帮助:)

【讨论】:

  • 我真的不介意什么包。问题是您在第二行获得了不需要的小数位。我想独立地联合格式化每一行的值。
  • 哦,这是一个有趣的问题。让我看看我能不能做到这一点。
  • 谢谢!正如我所说,我确实做到了,通过转置数据框然后应用format(),但这很尴尬。
猜你喜欢
  • 1970-01-01
  • 2019-08-01
  • 2020-06-11
  • 1970-01-01
  • 2021-11-15
  • 2021-04-01
  • 1970-01-01
  • 2017-06-17
  • 2018-01-10
相关资源
最近更新 更多