title: "crosstable"
author: "wintryheart"
date: "2022/9/11"
output: html_document
library(Statamarkdown)
stataexe <- "C:/Program Files/Stata17/StataMP-64.exe"
knitr::opts_chunk$set(engine.path=list(stata=stataexe))
knitr::opts_chunk$set(echo = TRUE, error=TRUE, cleanlog=TRUE, comment=NA)
一、问题
如果将二手汇总数据整理成可用于统计分析的数据。
1、 辛普森悖论
摘自百度百科
“校长,不好了,有很多男生在校门口抗议,他们说今年研究所女生录取率42%是男生21%的两倍,我们学校遴选学生有性别歧视”,校长满脸疑惑的问秘书:“我不是特别交代,今年要尽量提升男生录取率以免落人口实吗?”
秘书赶紧回答说:“确实有交代下去,我刚刚也查过,的确是有注意到,今年商学院录取率是男性75%,女性只有49%;而法学院录取率是男性10%,女性为5%。两个学院都是男生录取率比较高,校长这是我作的调查报告。”
学院 | 女生 | 女生 | 女生 | 男生 | 男生 | 男生 | 合计 | 合计 | 合计 |
---|---|---|---|---|---|---|---|---|---|
申请 | 录取 | 录取率 | 申请 | 录取 | 录取率 | 申请 | 录取 | 录取率 | |
商学院 | 100 | 49 | 49% | 20 | 15 | 75% | 120 | 64 | 53.30% |
法学院 | 20 | 1 | 5% | 100 | 10 | 10% | 120 | 11 | 9.20% |
总计 | 120 | 50 | 42% | 120 | 25 | 21% | 240 | 75 | 31.30% |
“秘书,你知道为什么个别录取率男皆大于女,但是总体录取率男却远小于女吗?”
2、目标数据集
每一交叉类别对应一个频数。
性别 | 学院 | 录取 | 频数 |
---|
- 性别(sex): 0=女生 1=男生
- 学院(school): 0=商学院 1=法学院
- 录取(pass): 0=未录取 1=录取
二、数据整理
1,只保留表格中的关键数据:构建其他数据的基础数据
学院 | 女生 | 女生 | 男生 | 男生 |
---|---|---|---|---|
申请 | 录取 | 申请 | 录取 | |
商学院 | 100 | 49 | 20 | 15 |
法学院 | 20 | 1 | 100 | 10 |
2,手工转换成符合习惯的数据集
性别 | 学院 | 申请 | 录取 |
---|---|---|---|
sex | school | apply | pass |
女生 | 商学院 | 100 | 49 |
女生 | 法学院 | 20 | 1 |
男生 | 商学院 | 20 | 15 |
男生 | 法学院 | 100 | 10 |
3,利用STATA处理数据集
clear
input sex school apply pass
0 0 100 49
0 1 20 1
1 0 20 15
1 1 100 10
end
list
# 生成宽表的唯一id
gen id=_n
# 将录用和申请变成count系列变量,为宽表变长表作准备
# count1表示录用的频数,count0表示没录用的频数
rename pass count1
gen count0=apply-count1
drop apply
list
# 宽表转长表,生成新变量pass,0=没录用 1=录用
reshape long count, i(id) j(pass)
list
school | |||||||||
---|---|---|---|---|---|---|---|---|---|
0 | 1 | Total | |||||||
sex | sex | sex | |||||||
0 | 1 | Total | 0 | 1 | Total | 0 | 1 | Total | |
pass=0 | 51 | 25 | 46.67 | 95 | 90 | 90.83 | 58.33 | 79.17 | 68.75 |
pass=1 | 49 | 75 | 53.33 | 5 | 10 | 9.17 | 41.67 | 20.83 | 31.25 |
4,补充:充分利用reshape整理数据
4.1 在1的基础上直接在Excel里转置成可以导入STATA的表。
学院 | 商学院 | 法学院 | |
---|---|---|---|
女生 | 申请 | 100 | 20 |
女生 | 录取 | 49 | 1 |
男生 | 申请 | 20 | 100 |
男生 | 录取 | 15 | 10 |
4.2 稍加调整变量名,直接粘贴导入 STATA
sex | pass | count0 | count1 |
---|---|---|---|
女生 | 申请 | 100 | 20 |
女生 | 录取 | 49 | 1 |
男生 | 申请 | 20 | 100 |
男生 | 录取 | 15 | 10 |
注:count0为商学院的频数,count1为法学院的频数
4.3 反复利用reshape命令进行整理
gen id=_n
reshape long count, i(id) j(school)
list
// 现在的频数是按性别和学院分的“申请”和“录取”的频数。
// “申请”是包含“录取”的,需要调整成互斥的分类,即“录取”和“没录取”。
// 因此,我们需要再做一次长宽表的调整,以生成“没录取”类别的频数。
// 在此之前,必须调整pass的赋值和变量属性,否则后面无法执行reshape命令
replace pass="2" if pass=="申请"
replace pass="1" if pass=="录取"
destring pass, replace
replace sex="0" if sex=="女生"
replace sex="1" if sex=="男生"
list
// 在长表变宽表前,还需要调整id的赋值。原来的id编码是围绕学院转换的。
// 围绕pass进行长宽表转换,需要满足两个条件:
// 1, id+pass的组合是唯一;2,id的取值是随pass的取值循环往复的
// 例如,本例中,pass=1时,对应的id分别为1、2、3、4;
// 同样,pass=2时,对应的id还是取这四个值。
// 4个一组其实也代表除pass之外,其他关键变量的组合是4种。变成宽表,那就是4行。
sort pass
forvalues n=0/1 {
replace id=_n-4*`n' if pass==`n'+1 //按pass的取值进行id赋值循环。
}
reshape wide count, i(id) j(pass)
list
// 生成“没录取”的频数
gen count0=count2-count1
list
drop count2
order id school sex count0 count1
// 再次转成长表,就符合期望的数据集了。
reshape long count, i(id) j(pass)
list
三、重新统计分析
# 列联表
table () (school sex) [fw=count], stat(fvpercent pass)
# 对数线性分析
glm pass sex school [fw=count], family(binomial)
# 二项logit回归
logit pass sex school [fw=count]
四、汇总数据转换成个体数据集
duplicates
命令是报告和删除重复数据。
expand
命令恰恰相反,复制数据。
利用expand
命令将分类汇总数据转换成个体数据变得非常简单。
expand count //根据count的值复制相应样本数。
tab pass
drop count //count变量不再有意义。
# 不带权重的二项logit回归
logit pass sex school