RVary by Row 由 knitr::kable 生成的数字的舍入



我正在尝试使用 knitr::kable 生成一个降价表,其中数字的舍入因行而异。例如,假设我有以下 data.frame:

example.df <- data.frame(a = c(0.1234, 2000), b = c(0.5678, 3000))

我想创建以下降价表,其中第一行四舍五入到两位数,第二行四舍五入为整数。

|    a|    b|
|----:|----:|
| 0.12| 0.57|
| 2000| 3000|

相反,我似乎只能格式化整个列。

library(knitr)
kable(example.df, digits = c(2, 0))

这导致以下降价表:

|       a|    b|
|-------:|----:|
|    0.12|    1|
| 2000.00| 3000|

关于如何在 R 中生成具有逐行数字格式的降价表的任何建议?

正如@user20650所指出的,一种解决方案是在将数据传递给knitr之前,以R格式转换数据帧中条目的格式。可以这样做:

example.df <- rbind(formatC(as.numeric(example.df[1,]),format="f",digits=2),
                    formatC(as.numeric(example.df[2,]),format="d"))
colnames(example.df) <- c("a","b")

这将给出以下输出:

> kable(example.df, align="r")
|    a|    b|
|----:|----:|
| 0.12| 0.57|
| 2000| 3000|

如果超过 4 或 5 行,则可能值得使用 mapply()以避免为每行重复一次formatC(...)

example.df <- data.frame(a = c(0.1234, 2000), b = c(0.5678, 3000))
example.df1 <- data.frame(t(example.df))  # Transpose for easy iteration
example.df1 <- mapply(  # Iterate over each column
  function(df, digits) {
    formatC(df, format="f", digits=digits)
  },
  df=example.df1, digits=c(2, 0)
)
example.df1 <- data.frame(t(example.df1))  # Transpose back
names(example.df1) <- names(example.df)  # Re-create names
kable(example.df1, row.names=FALSE)

在上面的代码中,您只需要将df=设置为要转换为表的data.framematrix,并digits=为指示每行中需要多少位数的向量。

如果您在多个表上重复此方法,也可以将其转换为函数。

digitsByRows <- function(df, digits) {
  tmp0 <- data.frame(t(df))
  tmp1 <- mapply(
    function(df0, digits0) {
      formatC(df0, format="f", digits=digits0)
    },
    df0=tmp0, digits0=digits
  )
  tmp1 <- data.frame(t(tmp1))
  names(tmp1) <- names(df)
  return(tmp1)
}
kable(digitsByRows(example.df, c(2, 0)), row.names=FALSE)

相关内容

最新更新