如何为两个分类变量创建列联表(交叉表)?
How to create a contingency tables (crosstab) for two categorical variables?
WHO 唐氏综合症数据库为您提供有关不同变量的 100 万婴儿中出生的唐氏综合症婴儿数量的信息。
我想创建一个交叉表,其中包含分类变量 Country
和 Year
的绝对频率、相对频率和边际频率
期望的结果类似于:
Year | 1978 1979 1980
Country | ----------------------------------------------------------------------
ALB | 76.4 78.5 87.6 ...
AUT | 87.6 67.9 80.0 …
AZE | 90.5 78.5 64.8 …
我尝试了几件事:
首先,为三个变量创建一个新的 df:
DS <- dplyr::select(DownSyndrome, YEAR, COUNTRY_REGION, VALUE)
但我不知道如何使用 table 以及与之交叉的功能。
我设法获得了绝对频率:
DS_wide <- DownSyndrome %>%
pivot_wider(
names_from = YEAR,
values_from = VALUE)
不过话又说回来,我不知道如何从这里得到相对频率和裕度频率。
感谢任何帮助,
谢谢
PS:
这是一个 dplyr
方法。
第一行根据您的代码将长格式转换为宽格式。第二行根据名称与纯数字模式匹配的所有列计算总计。第三行计算每个国家的相对总数。第四行将所有只有数字的列除以总列,并将它们分配给后缀为 _RELATIVE
的列。
library(tidyverse)
DownSyndrome %>%
pivot_wider(names_from = YEAR,values_from = VALUE) %>%
mutate(TOTAL = rowSums(.[grep("[0-9]+",names(.))],na.rm=TRUE)) %>%
mutate(TOTAL_RELATIVE = TOTAL / sum(TOTAL)) %>%
mutate_at(vars(matches("[0-9]+")), list(RELATIVE = ~ ./TOTAL))
# A tibble: 49 x 104
# COUNTRY COUNTRY_GRP SEX `2008` `2009` `2010` `2011` `2012` `2013` `2014` `2015` `2016` `2017` `1985` `1986` `1987` `1988`
# <fct> <fct> <fct> <int> <int> <int> <int> <int> <int> <int> <int> <int> <int> <int> <int> <int> <int>
# 1 ALB "" ALL 32 29 42 39 18 28 14 29 23 16 NA NA NA NA
# 2 AUT "" ALL 13 16 12 6 6 3 NA NA NA NA 23 29 39 24
# 3 AZE "" ALL 38 51 52 42 32 38 49 36 32 38 NA NA NA NA
# 4 BEL "" ALL 248 232 275 240 259 245 NA NA NA NA 56 126 152 126
# 5 BGR "" ALL 22 32 27 32 38 17 32 32 18 24 NA NA NA NA
# 6 BIH "" ALL NA NA NA NA NA NA NA NA NA NA 59 42 75 65
# 7 BLR "" ALL 69 60 44 61 46 50 56 53 63 56 NA NA NA NA
# 8 CHE "" ALL 121 107 127 145 152 152 131 108 112 86 NA NA NA NA
# 9 CZE "" ALL 43 49 46 53 49 45 45 43 NA NA NA NA NA 116
#10 DEU "" ALL 269 288 251 290 298 284 290 296 308 312 NA NA NA NA
如果你只想要相对值,你可以使用 select
.
DownSyndrome %>%
pivot_wider(names_from = YEAR,values_from = VALUE) %>%
mutate(TOTAL = rowSums(.[grep("[0-9]+",names(.))],na.rm=TRUE)) %>%
mutate(TOTAL_RELATIVE = TOTAL / sum(TOTAL)) %>%
mutate_at(vars(matches("[0-9]+")), list(RELATIVE = ~ ./TOTAL)) %>%
select(COUNTRY,matches("RELATIVE"),TOTAL_RELATIVE)
DownSyndrome <- read.csv("~/HFA_604_EN.csv",skip = 25)
WHO 唐氏综合症数据库为您提供有关不同变量的 100 万婴儿中出生的唐氏综合症婴儿数量的信息。
我想创建一个交叉表,其中包含分类变量 Country
和 Year
期望的结果类似于:
Year | 1978 1979 1980
Country | ----------------------------------------------------------------------
ALB | 76.4 78.5 87.6 ...
AUT | 87.6 67.9 80.0 …
AZE | 90.5 78.5 64.8 …
我尝试了几件事:
首先,为三个变量创建一个新的 df:
DS <- dplyr::select(DownSyndrome, YEAR, COUNTRY_REGION, VALUE)
但我不知道如何使用 table 以及与之交叉的功能。
我设法获得了绝对频率:
DS_wide <- DownSyndrome %>%
pivot_wider(
names_from = YEAR,
values_from = VALUE)
不过话又说回来,我不知道如何从这里得到相对频率和裕度频率。
感谢任何帮助, 谢谢
PS:
这是一个 dplyr
方法。
第一行根据您的代码将长格式转换为宽格式。第二行根据名称与纯数字模式匹配的所有列计算总计。第三行计算每个国家的相对总数。第四行将所有只有数字的列除以总列,并将它们分配给后缀为 _RELATIVE
的列。
library(tidyverse)
DownSyndrome %>%
pivot_wider(names_from = YEAR,values_from = VALUE) %>%
mutate(TOTAL = rowSums(.[grep("[0-9]+",names(.))],na.rm=TRUE)) %>%
mutate(TOTAL_RELATIVE = TOTAL / sum(TOTAL)) %>%
mutate_at(vars(matches("[0-9]+")), list(RELATIVE = ~ ./TOTAL))
# A tibble: 49 x 104
# COUNTRY COUNTRY_GRP SEX `2008` `2009` `2010` `2011` `2012` `2013` `2014` `2015` `2016` `2017` `1985` `1986` `1987` `1988`
# <fct> <fct> <fct> <int> <int> <int> <int> <int> <int> <int> <int> <int> <int> <int> <int> <int> <int>
# 1 ALB "" ALL 32 29 42 39 18 28 14 29 23 16 NA NA NA NA
# 2 AUT "" ALL 13 16 12 6 6 3 NA NA NA NA 23 29 39 24
# 3 AZE "" ALL 38 51 52 42 32 38 49 36 32 38 NA NA NA NA
# 4 BEL "" ALL 248 232 275 240 259 245 NA NA NA NA 56 126 152 126
# 5 BGR "" ALL 22 32 27 32 38 17 32 32 18 24 NA NA NA NA
# 6 BIH "" ALL NA NA NA NA NA NA NA NA NA NA 59 42 75 65
# 7 BLR "" ALL 69 60 44 61 46 50 56 53 63 56 NA NA NA NA
# 8 CHE "" ALL 121 107 127 145 152 152 131 108 112 86 NA NA NA NA
# 9 CZE "" ALL 43 49 46 53 49 45 45 43 NA NA NA NA NA 116
#10 DEU "" ALL 269 288 251 290 298 284 290 296 308 312 NA NA NA NA
如果你只想要相对值,你可以使用 select
.
DownSyndrome %>%
pivot_wider(names_from = YEAR,values_from = VALUE) %>%
mutate(TOTAL = rowSums(.[grep("[0-9]+",names(.))],na.rm=TRUE)) %>%
mutate(TOTAL_RELATIVE = TOTAL / sum(TOTAL)) %>%
mutate_at(vars(matches("[0-9]+")), list(RELATIVE = ~ ./TOTAL)) %>%
select(COUNTRY,matches("RELATIVE"),TOTAL_RELATIVE)
DownSyndrome <- read.csv("~/HFA_604_EN.csv",skip = 25)