R语言实现不同类型列分别执行Wilcox检验与Fisher检验的问题
列类型自动匹配检验方法代码修改方案
核心错误原因
- 列类型判断逻辑错误:未将当前检验的列ID与类型映射绑定,直接判断整个类型向量,触发长度警告且无法匹配对应检验方法
- 变量未定义报错:两个if分支仅会生成一个检验结果对象,但返回结果同时调用两个分支的对象
test和test1,必然触发对象不存在错误 - 索引越界错误:示例
combination中设置的列ID远大于测试数据的列数,运行直接报错 - 检验逻辑偏差:混淆了分组列取值与待检验特征列的逻辑,检验函数输入参数不符合要求
修改后完整实现
# 1. 原始列类型定义与映射构建 list.group <-list(list(id = 2, type = "num"), list(id = 3, type = "num"), list(id = 4, type = "cat"), list(id = 5, type = "cat")) # 构建列ID到类型的快速查找映射 col_type_map <- setNames( sapply(list.group, `[[`, "type"), as.character(sapply(list.group, `[[`, "id")) ) # 自定义待检验的列ID(替换为你实际需要检验的列) test_cols <- c(2,3,4) # 自定义要比较的GROUP分组取值 compare_groups <- c(1,2) # 2. 重写检验函数 auto_test_fun <- function(df, compare_group, test_cols, col_type_map){ # 筛选要比较的两组数据 df_filter <- df[df$GROUP %in% compare_group, ] # 遍历每个待检验列生成结果 do.call(rbind, lapply(test_cols, function(col_id) { # 查询当前列的类型 col_type <- col_type_map[as.character(col_id)] # 按类型匹配检验方法 if(col_type == "num"){ # 数值列执行wilcox检验 test_res <- wilcox.test( df_filter[[col_id]] ~ df_filter[["GROUP"]], exact = FALSE # 小样本场景关闭exact计算避免警告 ) # 数值列附加统计信息:两组中位数 stat_desc <- paste0( "Group", compare_group[1], "中位数:", round(median(df_filter[df_filter$GROUP == compare_group[1], col_id]),2), "; Group", compare_group[2], "中位数:", round(median(df_filter[df_filter$GROUP == compare_group[2], col_id]),2) ) } else if(col_type == "cat"){ # 分类列先构建列联表再执行fisher检验 cross_tab <- table(df_filter[[col_id]], df_filter[["GROUP"]]) test_res <- fisher.test(cross_tab) # 分类列附加统计信息:各组频数+占比 prop_tab <- round(prop.table(cross_tab, 2)*100, 1) stat_desc <- paste0( rownames(cross_tab), ": Group", compare_group[1], "(", cross_tab[,1], ",", prop_tab[,1], "%) ", "Group", compare_group[2], "(", cross_tab[,2], ",", prop_tab[,2], "%) ", collapse = ";" ) } # 组装结果行 data.frame( Test_info = paste0("列ID", col_id, "(", col_type,"): 分组", compare_group[1], "vs", compare_group[2]), p_value = round(test_res$p.value, 4), statistic = ifelse(col_type == "num", round(test_res$statistic,4), NA), stat_desc = stat_desc ) })) } # 3. 测试数据 data <- structure(list(GROUP = c(1L, 2L, 1L, 2L, 1L, 2L, 1L, 2L, 1L), col1 = c(23L, 432L, 234L, 234L, 3123L, 657L, 8768L, 123L, 42323L), col2 = c(567L, 765L, 8678L, 46L, 35L, 24L, 76L, 789L, 45L), col3 = c(1L, 3L, 5L, 7L, 8L, 0L, 8L, 7L, 3L), col4 = c("S", "S", "S", "S", "F", "F", "F", "F", "F")), class = "data.frame", row.names = c(NA, -9L)) # 4. 运行测试 result <- auto_test_fun(df = data, compare_group = compare_groups, test_cols = test_cols, col_type_map = col_type_map) print(result)
运行说明
运行代码后会自动匹配每个待检验列的类型,执行对应检验方法,最终输出包含检验信息、p值、统计量、分组统计描述的结果表。
内容的提问来源于stack exchange,提问作者GOGA GOGA
相关产品推荐
相关产品推荐

