You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

循环调用Shapiro.test报错,单独运行正常的技术问询

问题分析与修复

核心错误原因

你用c(data$ICU, data$Duration)这类方式创建变量列表时,实际是把多列向量合并成了一个超长向量,而非保存独立的完整列。循环里dependent_vars_ttest[[y]]取到的不是整列数据,只是这个长向量的第y个元素——样本量仅为1,自然触发shapiro.test的样本量范围报错。单独运行时你直接调用data$ICU取完整列,所以不会出问题。

修正后的完整代码

setwd("~/Desktop/Stats")

data <- read.csv("Stats.csv", header = TRUE)
# 建议用大写View(),避免和部分包的view()函数冲突
# View(data)

# 改用命名列表保存完整列,既保留数据又能直接获取变量名
independent_vars <- list(Smokes = data$Smokes, Anx = data$Anx, Depression = data$Depression)  
dependent_vars_ttest <- list(ICU = data$ICU, Duration = data$Duration) 
dependent_vars_chi2 <- list(Complication = data$Complication, X90 = data$X90)  

wb <- createWorkbook()

# 拆分循环:先处理t检验,再处理卡方检验,逻辑更清晰
# 处理t检验
for (iv_name in names(independent_vars)) {
  iv <- independent_vars[[iv_name]]
  for (dv_name in names(dependent_vars_ttest)) {
    dv <- dependent_vars_ttest[[dv_name]]
    
    # 过滤缺失值,避免检验报错
    valid_data <- na.omit(data.frame(iv = iv, dv = dv))
    if(nrow(valid_data) < 3) {
      warning(paste("样本量不足,跳过", iv_name, "vs", dv_name, "的t检验"))
      next
    }
    
    # 只做一次shapiro检验,减少重复计算
    shapiro_p <- shapiro.test(valid_data$dv)$p.value
    var_p <- var.test(dv ~ iv, data = valid_data)$p.value
    
    # 选择对应检验方法
    if (shapiro_p >= 0.05 && var_p >= 0.05) {
      t_test_result <- t.test(dv ~ iv, data = valid_data)
    } else if (shapiro_p >= 0.05) {
      t_test_result <- wilcox.test(dv ~ iv, data = valid_data)
    } else {
      t_test_result <- t.test(dv ~ iv, data = valid_data, var.equal = FALSE)
    }
    
    # 构建结果表格,存变量名而非变量值
    t_test_table <- data.frame(
      Variable = iv_name,
      Dependent_Variable = dv_name,
      Mean_Group_1 = if(!is.null(t_test_result$estimate[1])) t_test_result$estimate[1] else NA,
      Mean_Group_2 = if(!is.null(t_test_result$estimate[2])) t_test_result$estimate[2] else NA,
      SD_Group_1 = if(!is.null(t_test_result$sd[1])) t_test_result$sd[1] else NA,
      SD_Group_2 = if(!is.null(t_test_result$sd[2])) t_test_result$sd[2] else NA,
      p_value = t_test_result$p.value,
      CI_Lower = if(!is.null(t_test_result$conf.int[1])) t_test_result$conf.int[1] else NA,
      CI_Upper = if(!is.null(t_test_result$conf.int[2])) t_test_result$conf.int[2] else NA,
      stringsAsFactors = FALSE
    )
    
    # 工作表命名用变量组合,避免重复覆盖
    sheet_name <- paste0(iv_name, "_vs_", dv_name, "_t_test")
    addWorksheet(wb, sheetName = sheet_name)
    writeData(wb, sheet = sheet_name, x = t_test_table)
  }
}

# 处理卡方检验
for (iv_name in names(independent_vars)) {
  iv <- independent_vars[[iv_name]]
  for (dv_name in names(dependent_vars_chi2)) {
    dv <- dependent_vars_chi2[[dv_name]]
    
    # 过滤缺失值
    valid_data <- na.omit(data.frame(iv = iv, dv = dv))
    contingency_table <- table(valid_data$dv, valid_data$iv)
    
    # 卡方检验添加correct参数,避免低频数警告
    chi2_test_result <- chisq.test(contingency_table, correct = TRUE)
    
    # 构建易读的结果表格
    chi2_test_table <- data.frame(
      Variable = iv_name,
      Dependent_Variable = dv_name,
      Group = rep(rownames(contingency_table), ncol(contingency_table)),
      Category = rep(colnames(contingency_table), each = nrow(contingency_table)),
      Count = as.vector(contingency_table),
      Odds_Ratio = if(!is.null(chi2_test_result$estimate)) chi2_test_result$estimate else NA,
      Odds_Ratio_CI_Lower = if(!is.null(chi2_test_result$conf.int[1])) chi2_test_result$conf.int[1] else NA,
      Odds_Ratio_CI_Upper = if(!is.null(chi2_test_result$conf.int[2])) chi2_test_result$conf.int[2] else NA,
      p_value = chi2_test_result$p.value,
      stringsAsFactors = FALSE
    )
    
    sheet_name <- paste0(iv_name, "_vs_", dv_name, "_chi2_test")
    addWorksheet(wb, sheetName = sheet_name)
    writeData(wb, sheet = sheet_name, x = chi2_test_table)
  }
}

saveWorkbook(wb, "output.xlsx")

额外优化说明

  • 用命名列表替代c()合并,既保留完整列数据,又能直接调用变量名,避免结果表格里塞满向量值。
  • 拆分循环层级,避免原代码中z循环重复创建同名工作表的问题,逻辑更易维护。
  • 添加缺失值过滤,避免因NA导致的检验报错。
  • 对wilcox.test结果做判空处理,因为它不会返回均值、标准差等统计量,避免表格出现无效NA。

内容的提问来源于stack exchange,提问作者emerson

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.21 11:32:02