Как добавить столбец и строки для условных сводок во фрейм данных (итоги и проценты)? есть ли рабочий метод с использованием R? - PullRequest
0 голосов
/ 03 марта 2020

В целях представления мне часто приходится форматировать фрейм данных с итоговыми значениями и процентами столбцов и строк.

Условное распределение итогов и процентов по строкам условно просто: stackoverflow, например,

Итоговые значения столбца могут быть аккуратно распределены:

опция 1: stackoverflow, например

опция 2: использование функции пакета janitor adorn_totals (однако я бы Я предпочитаю найти способ, не добавляя больше пакетов в мой рабочий процесс).

Я застрял на следующем шаге, который заключается в добавлении строки столбца% ниже суммы столбца. В этой строке вычисляется сумма столбца (сумма столбца) в процентах от суммы таблицы (сумма таблицы).

Здесь я должен разделить рабочий процесс, чтобы выполнить следующие действия:

  1. создать переменная итога таблицы
  2. функция для вычисления процентного содержания вектора
  3. вычисление строки процентного значения столбца
  4. привязка строки процентного значения столбца к таблице

Этот процесс кажется тяжелым, и я уверен, что есть лучший способ; предложения приветствуются.

Это то, к чему я стремлюсь This is what I am aiming to achieve

Как только таблица генерируется, форматирование и приведение в порядок для целей презентации я обычно делаю с помощью flextable или kableExtra как второй проход.

MWE

library(tidyverse)

tib <- tibble(v1 = c("a", "b", "c"),
              v2 = 1:3,
              v3 = 4:6)

# piping row summaries and column totals
tib <- 
  tib %>% 
  mutate(r_sum = rowSums(.[2:3]),
         r_pc = r_sum * 100/sum(r_sum)) %>% 
  bind_rows(summarise_all(., funs(if(is.numeric(.)) sum(.) else "Total")))


# extract gross total
table_total <- tib$r_sum[4]

# function to calculate percentage * 2 as tib includes a column total row
calc_pc <- function(x) {sum(x) * 100 / (table_total * 2)}

# calculate column percentages
col_pc <- 
  tib %>% 
  summarise_at(vars(v1:r_sum), funs(if(is.numeric(.)) calc_pc(.) else "Column %"))

# finally bringing it all together for the desired result
tib <- 
  tib %>% 
  bind_rows(col_pc)



1 Ответ

0 голосов
/ 19 марта 2020

Используя janitor, мы можем сделать все, когда у нас есть предварительно рассчитанный итог.

(Обратите внимание, что здесь используется across из dplyr 1.0.0, поэтому вам может потребоваться remotes::install_github("tidyverse/dplyr").)

library(janitor, warn.conflicts = FALSE)
library(dplyr, warn.conflicts = FALSE)

tib <- tibble(v1 = c("a", "b", "c"), v2 = 1:3, v3 = 4:6)

total <- tib %>% select(is.numeric) %>% sum

tib %>% 
  adorn_totals(c("row", "col")) %>% 
  rowwise() %>%
  mutate("Row %" = round(sum(across(is.numeric))/total*50)) %>%
  ungroup %>%
  bind_rows(summarise(., across(is.numeric, ~round(sum(.)/total*50)))) %>%
  `[[<-`(nrow(.), 1, "Column %") %>%
  `[[<-`(nrow(.), ncol(.), NA)
#> # A tibble: 5 x 5
#>   v1          v2    v3 Total `Row %`
#> * <chr>    <dbl> <dbl> <dbl>   <dbl>
#> 1 a            1     4     5      24
#> 2 b            2     5     7      33
#> 3 c            3     6     9      43
#> 4 Total        6    15    21     100
#> 5 Column %    29    71   100      NA

Создано в 2020-03-18 пакетом Представить (v0.2.1)

Немного дольше, но все же прекрасно выполнимо без janitor.

library(dplyr, warn.conflicts = FALSE)

tib <- tibble(v1 = c("a", "b", "c"), v2 = 1:3, v3 = 4:6)

total <- tib %>% select(is.numeric) %>% sum

tib %>% 
  rowwise() %>%
  mutate(
    Total = sum(across(is.numeric)),
    "Row %" = round(sum(across(is.numeric))/total*50)
  ) %>%
  ungroup %>%
  bind_rows(summarise(., across(is.numeric, sum))) %>%
  `[[<-`(nrow(.), 1, "Total") %>%
  bind_rows(summarise(., across(is.numeric, ~round(sum(.)/total*50)))) %>%
  `[[<-`(nrow(.), 1, "Column %") %>%
  `[[<-`(nrow(.), ncol(.), NA)
#> # A tibble: 5 x 5
#>   v1          v2    v3 Total `Row %`
#> * <chr>    <dbl> <dbl> <dbl>   <dbl>
#> 1 a            1     4     5      24
#> 2 b            2     5     7      33
#> 3 c            3     6     9      43
#> 4 Total        6    15    21     100
#> 5 Column %    29    71   100      NA

Создано в 2020-03-18 пакетом Представить (v0.2.1)

Могут быть сделаны оба немного короче, если вас не волнуют названия строк, конечно.

...