R语言新手求助:生成类相关图样式的多变量二元数据交叉频率表
解决方案:生成科目共选交叉表
嘿,我来帮你搞定这个需求!你要的这种交叉表其实可以通过简单的矩阵运算实现,完全不用纠结table()或者ftable()的局限。咱们一步步来,用你给的示例数据演示:
步骤1:预处理数据
首先把你的数据里的2(未选修)转换成0,这样我们就得到一个二进制矩阵——1代表选修,0代表未选修,方便后续计算:
# 先运行你提供的示例数据生成代码 set.seed(1234) math <- sample(c(1,2), 10, replace = TRUE, prob = c(0.3, 0.7)) physics <- sample(c(1,2), 10, replace = TRUE, prob = c(0.3, 0.7)) it <- sample(c(1,2), 10, replace = TRUE, prob = c(0.3, 0.7)) biology <- sample(c(1,2), 10, replace = TRUE, prob = c(0.3, 0.7)) chemistry <- sample(c(1,2), 10, replace = TRUE, prob = c(0.3, 0.7)) df <- as.data.frame(cbind(math, physics, it, biology, chemistry)) # 把2替换为0,生成二进制矩阵 df_binary <- df df_binary[df_binary == 2] <- 0
步骤2:计算交叉表
用crossprod()函数计算二进制矩阵的交叉乘积,这个结果正好就是你要的表格:
# 生成目标交叉表 cross_table <- crossprod(df_binary) cross_table
运行这段代码后,你会得到完全符合需求的结果:
math physics it biology chemistry math 3 2 1 0 1 physics 2 3 1 0 1 it 1 1 3 1 1 biology 0 0 1 3 0 chemistry 1 1 1 0 3
- 对角线单元格是对应科目的选修人数(比如math的3人、biology的3人)
- 非对角线单元格是同时选修两个科目的人数(比如math和physics的2人、biology和chemistry的0人)
可选:调整为百分比格式
如果需要把对角线显示为100%,其余单元格显示占行科目选修人数的比例,可以这样处理:
# 生成百分比版本的交叉表 cross_table_pct <- cross_table / diag(cross_table) # 把对角线设为100% diag(cross_table_pct) <- 1 # 保留一位小数并转成百分比字符串 cross_table_pct <- apply(cross_table_pct, c(1,2), function(x) paste0(round(x*100, 1), "%")) cross_table_pct
这个方法完全适配你实际的12个科目、1000+样本的情况,矩阵运算效率很高,不用担心速度问题。
内容的提问来源于stack exchange,提问作者Nina
相关产品推荐
相关产品推荐

