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

在R循环中对数据框执行Shapiro检验时如何正确使用!!sym?

问题解决:R循环中计算配对差值的报错修正

错误原因

!!sym(i)是tidyverse专属的非标准求值语法,仅能在支持tidyeval的函数(如dplyr::summarise/mutate)中使用,with()函数不识别该语法,因此触发invalid argument type错误。此外,你的代码未考虑配对数据的ID对齐,直接用列索引相减可能导致差值匹配错误(若数据排序混乱)。

修正方案

以下提供两种可行的实现方式,均保证配对差值按ID正确计算:

方法1:基础R+宽格式转换(直观易读)

先将数据转为宽格式,让同一ID的A/B处理结果在同一行,再计算差值:

library(tidyverse)
library(readxl)
library(broom) # 需加载此包使用tidy()整理检验结果

# 读取数据
df <- read_excel(paste0(getwd(),"/Data.xlsm"), sheet="data")

# 转换为宽格式:每个指标的A/B结果分列为两列
df_wide <- df %>%
  select(ID, Treatment, Effect, Intake, Temperature) %>%
  pivot_wider(names_from = Treatment, values_from = c(Effect, Intake, Temperature))

# 遍历指定列
for (i in c("Effect","Intake", "Temperature")){
  # 计算配对差值(A - B,可根据需求改为B - A)
  mean_diff <- df_wide[[paste0(i, "_A")]] - df_wide[[paste0(i, "_B")]]
  
  # Shapiro正态性检验
  s_test <- tidy(shapiro.test(mean_diff))
  cat("\n=== ", i, "的Shapiro检验结果 ===\n")
  print(s_test)
  
  # 配对t检验
  t_test <- tidy(t.test(mean_diff, paired = TRUE))
  cat("\n=== ", i, "的配对t检验结果 ===\n")
  print(t_test)
  
  # 绘制差值直方图(直观判断正态性)
  p <- ggplot(data.frame(diff = mean_diff), aes(x = diff)) +
    geom_histogram(bins = 10, fill = "lightblue", color = "black") +
    labs(title = paste(i, "配对差值分布"), x = "差值(A-B)", y = "频数") +
    theme_minimal()
  print(p)
}

方法2:tidyverse循环(无需转格式)

利用tidyeval语法在dplyr函数内处理,直接按ID分组计算差值:

library(tidyverse)
library(readxl)
library(broom)

df <- read_excel(paste0(getwd(),"/Data.xlsm"), sheet="data")

for (i in c("Effect","Intake", "Temperature")){
  # 按ID分组,提取对应指标的A/B值并计算差值
  mean_diff <- df %>%
    group_by(ID) %>%
    summarise(diff = !!sym(i)[Treatment == "A"] - !!sym(i)[Treatment == "B"]) %>%
    pull(diff)
  
  # 正态性检验与t检验
  s_test <- tidy(shapiro.test(mean_diff))
  t_test <- tidy(t.test(mean_diff, paired = TRUE))
  
  cat("\n=== ", i, "统计结果 ===\n")
  print("Shapiro检验:")
  print(s_test)
  print("\n配对t检验:")
  print(t_test)
  
  # 绘制QQ图(更适合判断正态性)
  p <- ggplot(data.frame(diff = mean_diff), aes(sample = diff)) +
    geom_qq() +
    geom_qq_line(color = "red") +
    labs(title = paste(i, "差值QQ图"), subtitle = "偏离红线越远,正态性越差") +
    theme_minimal()
  print(p)
}

关键注意点

  1. 配对数据必须按ID对齐计算差值,否则会出现逻辑错误;
  2. broom::tidy()用于将检验结果转为结构化数据框,方便后续导出或查看;
  3. 若只需判断正态性,除Shapiro检验外,QQ图/直方图的直观判断也很重要(尤其样本量较小时,Shapiro检验敏感度有限)。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.10 01:35:58