假设我有以下数据:
A <- rep(c("A1", "A2", "A3"), 10)
B <- sample(1:5, size=30, replace=TRUE)
C <- sample(c("yes", "no"), size=30, replace=TRUE)
我想创建一个包含所有三个变量的表;A";定义列,B和C定义行。
在rbase中,我会这样做:
data.frame(rbind(table(B, A),
table(C, A)))
这将给出以下输出:
A1 A2 A3
1 0 3 3
2 2 1 0
3 2 1 2
4 2 4 3
5 4 1 2
no 5 7 3
yes 5 3 7
变量";A";定义列;B";以及";C";定义行。
我的问题是:
在tidyverse中如何使用dplyr、group_by和summary来完成此操作?
有没有可能将比例添加到每个单元格中,使其看起来像这样:
A1 A2 A3
1 0(0%(3(1%(3(10%(
2 2(1%(1(0.5(0(0%(
3 2(1%(1(0.5(2(5%(
4 2(2%(4(2%(3(3%(
5 4(6%(1(1%(2(2%(
无5(7%(7(4%(3(3%(
是5(3%(3(2%(7(10%(
Thx提前。。。。
A <- rep(c("A1", "A2", "A3"), 10)
B <- sample(1:5, size=30, replace=TRUE)
C <- sample(c("yes", "no"), size=30, replace=TRUE)
total_n <- 30
library(tidyverse)
tibble(A,B = as.character(B),C) %>%
pivot_longer(c(B,C), names_to = "original_col", values_to = "label") %>%
count(A, label, name = "n") %>%
complete(A, label, fill = list(n=0)) %>%
transmute(A, label, val = sprintf("%s (%s%%)", n, formatC(100* n/total_n, digits = 2))) %>%
pivot_wider(names_from = A, values_from = val)
#> # A tibble: 7 × 4
#> label A1 A2 A3
#> <chr> <chr> <chr> <chr>
#> 1 1 0 ( 0%) 2 (6.7%) 2 (6.7%)
#> 2 2 3 ( 10%) 2 (6.7%) 2 (6.7%)
#> 3 3 4 ( 13%) 1 (3.3%) 2 (6.7%)
#> 4 4 3 ( 10%) 1 (3.3%) 4 ( 13%)
#> 5 5 0 ( 0%) 4 ( 13%) 0 ( 0%)
#> 6 no 2 (6.7%) 4 ( 13%) 5 ( 17%)
#> 7 yes 8 ( 27%) 6 ( 20%) 5 ( 17%)
创建于2022-09-15由reprex包(v2.0.1(
您可以使用dplyr::across()
并在每列上循环:
set.seed(123)
A <- rep(c("A1", "A2", "A3"), 10)
B <- sample(1:5, size=30, replace=TRUE)
C <- sample(c("yes", "no"), size=30, replace=TRUE)
dat <- data.frame(rbind(table(B, A),
table(C, A)))
library(dplyr)
dat %>%
transmute(across(starts_with("A"),
~ paste0(.x, " (", round(.x / sum(dat), 2) * 100, "%)")))
#> A1 A2 A3
#> 1 3 (5%) 3 (5%) 0 (0%)
#> 2 1 (2%) 2 (3%) 3 (5%)
#> 3 4 (7%) 4 (7%) 1 (2%)
#> 4 2 (3%) 0 (0%) 2 (3%)
#> 5 0 (0%) 1 (2%) 4 (7%)
#> no 5 (8%) 0 (0%) 4 (7%)
#> yes 5 (8%) 10 (17%) 6 (10%)
创建于2022-09-15由reprex包(v2.0.1(
使用janitor
set.seed(123)
library(magrittr)
library(janitor)
A <- rep(c("A1", "A2", "A3"), 10)
B <- sample(1:5, size=30, replace=TRUE)
C <- sample(c("yes", "no"), size=30, replace=TRUE)
dat <- data.frame(rbind(table(B, A),
table(C, A)))
dat %>%
adorn_totals("col") %>%
adorn_percentages("row") %>%
adorn_pct_formatting(digits = 1) %>%
adorn_ns(position = "front")
#> A1 A2 A3 Total
#> 3 3 (100.0%) 0 (0.0%) 3 (100.0%)
#> 1 2 (40.0%) 3 (60.0%) 5 (100.0%)
#> 4 4 (80.0%) 1 (20.0%) 5 (100.0%)
#> 2 0 (0.0%) 2 (100.0%) 2 (100.0%)
#> 0 1 (20.0%) 4 (80.0%) 5 (100.0%)
#> 5 0 (0.0%) 4 (100.0%) 4 (100.0%)
#> 5 10 (62.5%) 6 (37.5%) 16 (100.0%)
创建于2022-09-15,reprex v2.0.2