Используя 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)
Могут быть сделаны оба немного короче, если вас не волнуют названия строк, конечно.