如何在R中绘制二元变量共现实例数量统计图?
在R中绘制二元因子变量的共现次数统计图
Absolutely可以实现!你想要展示的是0/1因子变量两两同时取1的实例数量,最适合的可视化方式是热力图(清晰展示所有两两组合的数值),也可以用网络图来突出关联强弱。我会用ggplot2和tidyverse工具帮你完成,步骤很清晰:
1. 数据预处理:将因子转为数值型
因为因子类型无法直接参与计算,我们先把所有列转成数值型的0/1:
# 加载你的数据集 df <- structure(list(english = structure(c(2L, 1L, 2L, 1L, 2L, 2L, 2L, 2L, 1L, 2L, 2L), .Label = c("0", "1"), class = "factor"), math = structure(c(2L, 1L, 1L, 2L, 2L, 2L, 2L, 2L, 1L, 1L, 1L), .Label = c("0", "1"), class = "factor"), science = structure(c(1L, 1L, 2L, 1L, 1L, 2L, 1L, 1L, 1L, 2L, 1L), .Label = c("0", "1"), class = "factor"), history = structure(c(2L, 2L, 1L, 2L, 1L, 1L, 1L, 1L, 2L, 2L, 2L), .Label = c("0", "1"), class = "factor"), art = structure(c(2L, 1L, 1L, 2L, 1L, 2L, 2L, 1L, 1L, 2L, 2L), .Label = c("0", "1"), class = "factor"), geography = structure(c(1L, 2L, 2L, 1L, 1L, 2L, 2L, 2L, 1L, 1L, 1L), .Label = c("0", "1"), class = "factor")), row.names = c(NA, -11L), class = c("tbl_df", "tbl", "data.frame")) # 把所有因子列转为数值型(0/1) library(dplyr) df_num <- df %>% mutate(across(everything(), ~ as.numeric(as.character(.x))))
2. 计算两两变量的共现次数矩阵
这里用crossprod()超级高效,因为两个0/1向量的点积刚好就是它们同时为1的实例数:
# 计算共现矩阵 co_occur <- crossprod(df_num) # 转成ggplot需要的长格式 library(tidyr) co_occur_long <- co_occur %>% as.data.frame() %>% rownames_to_column("var1") %>% pivot_longer(cols = -var1, names_to = "var2", values_to = "count")
3. 用ggplot2绘制热力图
每个单元格的颜色深浅和内部数字对应共现次数,直观清晰:
library(ggplot2) ggplot(co_occur_long, aes(x = var1, y = var2, fill = count)) + geom_tile(color = "white") + # 白色边框区分每个单元格 geom_text(aes(label = count), color = "black", size = 4) + # 显示具体数值 scale_fill_gradient(low = "#f0f9e8", high = "#006d2c") + # 渐变配色,浅到深绿 labs(title = "变量同时取1的实例数量热力图", x = "", y = "", fill = "共现次数") + theme_minimal() + theme(axis.text.x = element_text(angle = 45, hjust = 1)) # x轴标签倾斜,避免重叠
在这个图里,你能直接看到english和math的共现次数是5,和你手动计算的结果完全一致。
可选:用网络图展示关联强度
如果想要更直观地体现变量间的关联紧密程度,可以用igraph包绘制网络图:
library(igraph) # 整理网络图数据(去掉对角线和重复的边) graph_data <- co_occur_long %>% filter(var1 < var2) %>% filter(count > 0) # 构建并绘制网络图 g <- graph_from_data_frame(graph_data, directed = FALSE) plot(g, edge.width = E(g)$count, # 边越粗代表共现次数越多 vertex.size = 20, vertex.label.cex = 0.8, edge.color = "#006d2c", main = "变量共现次数网络图")
两种可视化方式都能完美满足你的需求,按需选择就好!
内容的提问来源于stack exchange,提问作者Vale Y
相关产品推荐
相关产品推荐

