尝试按组获取频率计数和 R 中数据框中每一列的百分比
Trying to get frequnecy counts and percent by group of each column in data frame in R
我有这样的数据:
pat# sex race group bmi
1 F Black 1 4
2 M Asian 2 8
3 M Asian 3 19
4 M Asian 1 35
5 F Black 2 12
6 F Black 3 33
7 M White 1 2
8 F Black 2 35
9 M Asian 3 6
10 F Black 1 13
11 F Black 2 18
12 F Asian 3 1
13 M White 1 36
14 F Asian 2 25
15 M White 3 6
16 M White 1 20
17 F Black 2 3
18 M Asian 3 23
19 F Black 1 26
20 F Asian 2 13
21 M White 3 21
22 M White 1 16
23 F Black 2 29
24 F Black 3 19
25 M Asian 1 17
26 M Asian 2 22
27 F Black 3 26
我想得到每个变量的频率和每个变量的分组百分比,如下所示:
n 1 2 3
sex M frequency % % %
F frequency % % %
下一个变量:
n 1 2 3
race White frequency % % %
Asian frequency % % %
Black frequency % % %
变量很多,所以我不想一一列出。我尝试使用 xtabs()
和 dplyr
包来使用 R 的矢量功能 (df[2:30]
),但我没有让它工作。哪个包或函数并不重要,但希望使其足够灵活,以便将来使用不同列名和具有不同维度的数据。非常感谢任何建议!!
一种方法是使用 janitor
包,但它也会将总数更改为百分比:
library(janitor)
df %>%
tabyl(sex, group) %>%
adorn_totals("col") %>%
adorn_percentages() %>%
adorn_pct_formatting(digits = 2)
sex 1 2 3 Total
F 21.43% 50.00% 28.57% 100.00%
M 46.15% 15.38% 38.46% 100.00%
#But we could also choose counts
df %>%
tabyl(sex, group) %>%
adorn_totals("col")
sex 1 2 3 Total
F 3 7 4 14
M 6 2 5 13
一个tidyverse
方式是-
library(tidyverse)
df %>%
count(sex, group) %>%
group_by(sex) %>%
mutate(n = prop.table(n) * 100) %>%
pivot_wider(names_from = group, values_from = n, values_fill = 0)
# sex `1` `2` `3`
# <chr> <dbl> <dbl> <dbl>
#1 F 21.4 50 28.6
#2 M 46.2 15.4 38.5
如果你想对多个变量执行此操作,你可以使用 map
-
cols <- c('sex', 'race')
map(cols, ~df %>%
count(.data[[.x]], group) %>%
group_by(.data[[.x]]) %>%
mutate(n = prop.table(n) * 100) %>%
pivot_wider(names_from = group, values_from = n, values_fill = 0) %>%
ungroup)
#[[1]]
# A tibble: 2 x 4
# sex `1` `2` `3`
# <chr> <dbl> <dbl> <dbl>
#1 F 21.4 50 28.6
#2 M 46.2 15.4 38.5
#[[2]]
# A tibble: 3 x 4
# race `1` `2` `3`
# <chr> <dbl> <dbl> <dbl>
#1 Asian 20 40 40
#2 Black 27.3 45.5 27.3
#3 White 66.7 0 33.3
如果你需要频率,你可以这样做:
lapply(df[2:3], table, df$group)
$race
1 2 3
Asian 2 4 4
Black 3 5 3
White 4 0 2
$group
1 2 3
1 9 0 0
2 0 9 0
3 0 0 9
如果您需要百分比,则必须定义您需要的百分比,即按行、按列、总计等
如果需要按行:
lapply(df[2:3], function(x)prop.table(table(x, df$group),1)*100)
$sex
x 1 2 3
F 21.42857 50.00000 28.57143
M 46.15385 15.38462 38.46154
$race
x 1 2 3
Asian 20.00000 40.00000 40.00000
Black 27.27273 45.45455 27.27273
White 66.66667 0.00000 33.33333
我能够使用 table()
函数和 tigerstats
包来做到这一点。我遇到的主要问题是 R 会以不同于 CSV 数据集的方式对待 SAS 数据集。白天和黑夜!
我有这样的数据:
pat# sex race group bmi
1 F Black 1 4
2 M Asian 2 8
3 M Asian 3 19
4 M Asian 1 35
5 F Black 2 12
6 F Black 3 33
7 M White 1 2
8 F Black 2 35
9 M Asian 3 6
10 F Black 1 13
11 F Black 2 18
12 F Asian 3 1
13 M White 1 36
14 F Asian 2 25
15 M White 3 6
16 M White 1 20
17 F Black 2 3
18 M Asian 3 23
19 F Black 1 26
20 F Asian 2 13
21 M White 3 21
22 M White 1 16
23 F Black 2 29
24 F Black 3 19
25 M Asian 1 17
26 M Asian 2 22
27 F Black 3 26
我想得到每个变量的频率和每个变量的分组百分比,如下所示:
n 1 2 3
sex M frequency % % %
F frequency % % %
下一个变量:
n 1 2 3
race White frequency % % %
Asian frequency % % %
Black frequency % % %
变量很多,所以我不想一一列出。我尝试使用 xtabs()
和 dplyr
包来使用 R 的矢量功能 (df[2:30]
),但我没有让它工作。哪个包或函数并不重要,但希望使其足够灵活,以便将来使用不同列名和具有不同维度的数据。非常感谢任何建议!!
一种方法是使用 janitor
包,但它也会将总数更改为百分比:
library(janitor)
df %>%
tabyl(sex, group) %>%
adorn_totals("col") %>%
adorn_percentages() %>%
adorn_pct_formatting(digits = 2)
sex 1 2 3 Total
F 21.43% 50.00% 28.57% 100.00%
M 46.15% 15.38% 38.46% 100.00%
#But we could also choose counts
df %>%
tabyl(sex, group) %>%
adorn_totals("col")
sex 1 2 3 Total
F 3 7 4 14
M 6 2 5 13
一个tidyverse
方式是-
library(tidyverse)
df %>%
count(sex, group) %>%
group_by(sex) %>%
mutate(n = prop.table(n) * 100) %>%
pivot_wider(names_from = group, values_from = n, values_fill = 0)
# sex `1` `2` `3`
# <chr> <dbl> <dbl> <dbl>
#1 F 21.4 50 28.6
#2 M 46.2 15.4 38.5
如果你想对多个变量执行此操作,你可以使用 map
-
cols <- c('sex', 'race')
map(cols, ~df %>%
count(.data[[.x]], group) %>%
group_by(.data[[.x]]) %>%
mutate(n = prop.table(n) * 100) %>%
pivot_wider(names_from = group, values_from = n, values_fill = 0) %>%
ungroup)
#[[1]]
# A tibble: 2 x 4
# sex `1` `2` `3`
# <chr> <dbl> <dbl> <dbl>
#1 F 21.4 50 28.6
#2 M 46.2 15.4 38.5
#[[2]]
# A tibble: 3 x 4
# race `1` `2` `3`
# <chr> <dbl> <dbl> <dbl>
#1 Asian 20 40 40
#2 Black 27.3 45.5 27.3
#3 White 66.7 0 33.3
如果你需要频率,你可以这样做:
lapply(df[2:3], table, df$group)
$race
1 2 3
Asian 2 4 4
Black 3 5 3
White 4 0 2
$group
1 2 3
1 9 0 0
2 0 9 0
3 0 0 9
如果您需要百分比,则必须定义您需要的百分比,即按行、按列、总计等
如果需要按行:
lapply(df[2:3], function(x)prop.table(table(x, df$group),1)*100)
$sex
x 1 2 3
F 21.42857 50.00000 28.57143
M 46.15385 15.38462 38.46154
$race
x 1 2 3
Asian 20.00000 40.00000 40.00000
Black 27.27273 45.45455 27.27273
White 66.66667 0.00000 33.33333
我能够使用 table()
函数和 tigerstats
包来做到这一点。我遇到的主要问题是 R 会以不同于 CSV 数据集的方式对待 SAS 数据集。白天和黑夜!