R语言如何将2×2列联表展开为逐行记录的长格式数据
问题原因
epitools::expand.table() 运行不符合预期,是因为传入的对象是普通汇总数据框,不是函数要求的携带完整维度名称属性的table类对象。直接传入普通数据框时,函数无法正确识别行、列维度对应的分类变量和对应频数,自然无法输出正确的展开结果。
可用实现方法
方法1:修正输入格式后正常使用
expand.table
先将汇总数据框转为标准R列联表对象,设置好维度名后再调用函数:library(epitools) # 构造原始汇总表 tab_df <- data.frame( 性别 = c("男性", "女性"), 是 = c(2, 1), 否 = c(1, 2) ) # 转换为带维度名的table对象 crosstab <- as.table(as.matrix(tab_df[, -1])) dimnames(crosstab) <- list( 性别 = tab_df$性别, 结果 = c("是", "否") ) # 展开为单观测长表 long_data <- expand.table(crosstab)运行后得到的
long_data与目标结构完全一致。方法2:基础R实现,无额外包依赖
不需要加载第三方包,通过基础R的变形、行重复逻辑即可实现:# 宽表转带频数列的中间长表 mid_table <- reshape( tab_df, direction = "long", varying = c("是", "否"), v.names = "频数", timevar = "结果", times = c("是", "否") ) # 按频数重复行,重置行名得到最终结果 long_data_base <- mid_table[rep(seq_len(nrow(mid_table)), mid_table$频数), c("性别", "结果")] rownames(long_data_base) <- NULL方法3:tidyverse 语法实现
日常使用tidyverse生态的话,代码可读性更高:library(tidyr) library(dplyr) long_data_tidy <- tab_df |> pivot_longer(cols = c("是", "否"), names_to = "结果", values_to = "频数") |> uncount(频数)
三种方法输出结果完全相同,可根据自己的代码使用习惯选择。
内容的提问来源于stack exchange,提问作者code_rookie
相关产品推荐
相关产品推荐

