我正在尝试使用 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.frame
或matrix
,并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)