big.mark =, не работает с функцией kable в Rmarkdown при транспонировании фрейма данных

У меня есть фрейм данных с одной строкой и множеством столбцов, и я хочу представить его с помощью функции kable в Rmarkdown (вывод 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 = ","))
```

В первой таблице первое число отображается как: 1000. а в других таблицах они отображаются как: 1000. Я хочу, чтобы все было похоже на первую.

Спасибо!


person R.S    schedule 29.10.2018    source источник


Ответы (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"

Основная проблема с каждым из них заключается в том, что после этих преобразований вы затем вызываете функции форматирования - предоставляя big.mark аргумент kable или напрямую используя format вызов функции kable - для строк, тогда как они работают только с числами.

Вместо этого вы можете начать со всего числа (или установить stringsAsFactors = FALSE), установить желаемое форматирование для каждого из этих столбцов, а затем использовать функцию изменения формы, предназначенную для работы с фреймами данных. Один из распространенных вариантов - tidyr::gather, который предоставит вам данные более длинной формы, которые вы искали, но сохраните их как фрейм данных / тиббл.

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

Создано 29.10.2018 с помощью пакета REPEX (v0.2.1)

person camille    schedule 29.10.2018