【问题标题】:big.mark = "," doesn't work with kable function in Rmarkdown when transposing the data frame转置数据帧时,big.mark = "," 不适用于 Rmarkdown 中的 kable 函数
【发布时间】:2019-04-02 15:59:24
【问题描述】:

我有一个一行多列的数据框,我想用 Rmarkdown 中的 kable 函数来呈现它(PDF 输出)。为了以更好的方式呈现它,我使用了“转置”功能并生成了一个新的数据框。问题是当我使用: big.mark = "," 时,它不适用于转置的数据帧,尽管它在我使用原始数据帧时有效。 我在这里通过我编写的代码附上了这个问题的一个例子来演示这个问题:

```{r warning = FALSE, error = FALSE, message=FALSE, echo = FALSE, results = 
'hide'}
library(kableExtra)
library(tidyverse)
```

```{r warning = FALSE, error = FALSE, message=FALSE, echo = FALSE}
df <- data.frame(x=1000, y=scales::percent(0.34), z=500000)
kable(df, format = "latex", caption = "big.mark problem", booktabs=TRUE, 
format.args = list(big.mark = ","))
```

```{r warning = FALSE, error = FALSE, message=FALSE, echo = FALSE}
df_transpose <- t(data.frame(x=1000, y=scales::percent(0.34), z=500000))
kable(df_transpose, format = "latex", caption = "big.mark problem", 
booktabs=TRUE, format.args = list(big.mark = ","))
```

```{r warning = FALSE, error = FALSE, message=FALSE, echo = FALSE}
df_transpose_df <- as.data.frame(t(data.frame(x=1000, 
y=scales::percent(0.34), z=500000)))
kable(df_transpose_df, format = "latex", caption = "big.mark problem", 
booktabs=TRUE, format.args = list(big.mark = ","))
```

```{r warning = FALSE, error = FALSE, message=FALSE, echo = FALSE}
df_transpose_tibble <- as.tibble(t(data.frame(x=1000, 
y=scales::percent(0.34), z=500000)))
kable(df_transpose_tibble, format = "latex", caption = "big.mark problem", 
booktabs=TRUE, format.args = list(big.mark = ","))
```

第一个表显示第一个数字为:1,000。 其他表显示为:1000。 我希望一切看起来都像第一个。

谢谢!

【问题讨论】:

    标签: r latex knitr transpose kable


    【解决方案1】:

    您在这里遇到了数据类型问题。暂时忘掉kable 的东西,仔细研究您创建的每个对象的类和结构。

    首先是scales::percent 格式化一个数字并返回一个字符串。

    library(dplyr)
    library(tidyr)
    
    scales::percent(0.34)
    #> [1] "34.0%"
    class(scales::percent(0.34))
    #> [1] "character"
    

    因为data.frame 有一个默认的stringsAsFactors = TRUE,您为y 创建的字符串现在是一个因素--也许不是问题,但可能很尴尬,而不是您所期望的。

    df <- data.frame(x=1000, y=scales::percent(0.34), z=500000)
    df
    #>      x     y     z
    #> 1 1000 34.0% 5e+05
    class(df)
    #> [1] "data.frame"
    str(df)
    #> 'data.frame':    1 obs. of  3 variables:
    #>  $ x: num 1000
    #>  $ y: Factor w/ 1 level "34.0%": 1
    #>  $ z: num 5e+05
    

    查看t 的文档:它返回一个矩阵。矩阵只有一种数据类型,所以一切都被强制转换为字符串。

    df_transpose <- t(data.frame(x=1000, y=scales::percent(0.34), z=500000))
    class(df_transpose)
    #> [1] "matrix"
    str(df_transpose)
    #>  chr [1:3, 1] "1000" "34.0%" "5e+05"
    #>  - attr(*, "dimnames")=List of 2
    #>   ..$ : chr [1:3] "x" "y" "z"
    #>   ..$ : NULL
    

    当您再次将其转换为数据框时,您再次获得了因子,而不是任何数值。

    df_transpose_df <- as.data.frame(t(data.frame(x=1000, y=scales::percent(0.34), z=500000)))
    class(df_transpose_df)
    #> [1] "data.frame"
    str(df_transpose_df)
    #> 'data.frame':    3 obs. of  1 variable:
    #>  $ V1: Factor w/ 3 levels "1000","34.0%",..: 1 2 3
    #>   ..- attr(*, "names")= chr  "x" "y" "z"
    

    as_tibble 不强制转换为因数,因此这里与之前的 df 不同之处在于您拥有所有字符串而不是因数。

    df_transpose_tibble <- as_tibble(t(data.frame(x=1000, y=scales::percent(0.34), z=500000)))
    class(df_transpose_tibble)
    #> [1] "tbl_df"     "tbl"        "data.frame"
    str(df_transpose_tibble)
    #> Classes 'tbl_df', 'tbl' and 'data.frame':    3 obs. of  1 variable:
    #>  $ V1: chr  "1000" "34.0%" "5e+05"
    

    每个问题的根本问题是,在这些转换之后,您将调用格式化函数——向kable 提供big.mark 参数,或直接使用format 函数kable 调用——对字符串,而它们只对数字进行操作。

    相反,您可以从所有数字开始(或设置stringsAsFactors = FALSE),为每列设置所需的格式,然后使用专为处理数据框而设计的整形函数。一个常见的选项是tidyr::gather,它将为您提供您正在寻找的较长形状的数据,但将其保留为数据框/tibble。

    all_numeric <- data.frame(x = 1000, y = 0.34, z = 500000)
    all_numeric %>%
      mutate(x = formatC(x, big.mark = ","),
             y = scales::percent(y)) %>%
      gather(key, value)
    #>   key value
    #> 1   x 1,000
    #> 2   y 34.0%
    #> 3   z 5e+05
    

    reprex package (v0.2.1) 于 2018 年 10 月 29 日创建

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-08-10
      • 2019-07-08
      • 1970-01-01
      • 2020-03-16
      相关资源
      最近更新 更多