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

如何在R中对不同长度文件执行重复测量ANOVA分析?

问题描述

我开展了一项被试内研究,40名被试完成了全部三种条件的测试:Spheres、Rubber Bands、Arrows。每个被试对应三个输出文件,每个文件对应一种条件,包含三列:marker(与ANOVA分析无关)、error、timestamp。这些文件体积庞大且长度各异(因被试测试时长不同),我不清楚如何合并文件在R中进行ANOVA分析,也对文件长度不同的问题感到担忧。我考虑提取每个文件的error均值,再基于该均值进行ANOVA分析,但不确定这种方法是否合理。

补充信息

  • 文件大小范围:714KB 至 84107KB
  • 部分数据示例(通过dput()输出):
First1ArrowsDance2 <- 
  structure(
    list(
      markers = c(
        "Avatar Stopped",
        "Correct",
        "Correct",
        "Correct",
        "Correct",
        "Correct",
        "Correct",
        "Correct",
        "Correct",
        "Correct"
      ),
      error = c(
        0.2950831,
        0.2950782,
        0.2950698,
        0.295059,
        0.291691,
        0.2916831,
        0.2916784,
        0.2916738,
        0.2916692,
        0.2916639
      ),
      timestamp = c(
        48.28341,
        48.29302,
        48.30605,
        48.31171,
        48.3166,
        48.32151,
        48.32629,
        48.33191,
        48.33756,
        48.34245
      )
    ),
    row.names = c(NA,
                  10L),
    class = "data.frame"
  )

First1SpheresDance3 <- 
  structure(
    list(
      markers = c(
        "Avatar Stopped",
        "Correct",
        "Correct",
        "Correct",
        "Correct",
        "Correct",
        "Correct",
        "Correct",
        "Correct",
        "Correct"
      ),
      error = c(
        0.2382652,
        0.2382898,
        0.2382811,
        0.2382223,
        0.2382176,
        0.2382117,
        0.2382296,
        0.2382211,
        0.236873,
        0.2368683
      ),
      timestamp = c(
        40.74294,
        40.74847,
        40.7535,
        40.76012,
        40.77242,
        40.77939,
        40.78485,
        40.79016,
        40.80041,
        40.8057
      )
    ),
    row.names = c(NA,
                  10L),
    class = "data.frame"
  )

Second2RubberBandsDance3 <- 
  structure(
    list(
      markers = c(
        "Avatar Stopped",
        "Correct",
        "Correct",
        "Correct",
        "Correct",
        "Correct",
        "Correct",
        "Correct",
        "Correct",
        "Correct"
      ),
      error = c(
        0.4020498,
        0.4020442,
        0.4020512,
        0.4020622,
        0.402067,
        0.4020713,
        0.4027897,
        0.4027941,
        0.4027986,
        0.4028135
      ),
      timestamp = c(
        57.91049,
        57.92506,
        57.93127,
        57.9364,
        57.94205,
        57.94752,
        57.95326,
        57.96183,
        57.96772,
        57.97733
      )
    ),
    row.names = c(NA,
                  10L),
    class = "data.frame"
  )

解决方案

一、提取均值做被试内ANOVA是否合理?

这种方法完全合理。如果你的研究核心是比较三种条件下的整体error水平,取每个被试在对应条件下的error均值,正好满足被试内ANOVA的要求——每个被试在每个条件下有一个独立的观测值。

但要注意:这种汇总方式会丢失原始数据中的时间序列信息(比如error随测试时长的变化趋势)。如果error存在练习效应、疲劳效应,或者你想考察条件与时间的交互作用,那么直接分析原始数据能挖掘更多信息。

二、R中具体实现步骤

方式1:基于均值的被试内ANOVA

步骤1:批量读取文件并计算均值

假设文件命名规则包含被试ID和条件信息(如First1ArrowsDance2.csv对应被试First1、条件Arrows),用tidyverse批量处理:

library(tidyverse)

# 设置文件所在文件夹路径
data_dir <- "你的文件存储路径"

# 获取所有csv文件路径
file_paths <- list.files(data_dir, pattern = "\\.csv$", full.names = TRUE)

# 批量读取、提取被试/条件信息、计算error均值
mean_data <- map_dfr(file_paths, function(path) {
  df <- read_csv(path, col_types = cols(marker = col_character(), error = col_double(), timestamp = col_double()))
  file_name <- basename(path)
  
  # 从文件名提取被试ID和条件(根据你的实际命名规则调整正则表达式)
  subject_id <- str_extract(file_name, "^[A-Za-z0-9]+")
  condition <- str_extract(file_name, "(Spheres|Rubber Bands|Arrows)")
  
  tibble(
    subject_id = subject_id,
    condition = condition,
    mean_error = mean(df$error, na.rm = TRUE)
  )
})

步骤2:执行被试内ANOVA

可以用基础包的aov(),或更稳健的线性混合模型:

# 基础被试内ANOVA(自动处理球形假设校正)
aov_model <- aov(mean_error ~ condition + Error(subject_id/condition), data = mean_data)
summary(aov_model)

# 线性混合模型(更适合被试内设计,结果更稳健)
library(lme4)
lmm_model <- lmer(mean_error ~ condition + (1|subject_id), data = mean_data)
summary(lmm_model)
anova(lmm_model)

方式2:基于原始数据的线性混合模型(保留时间信息)

如果想利用全部原始数据,考察error随时间的变化及条件的影响,用混合模型处理不同长度的文件:

步骤1:批量读取并合并原始数据

full_data <- map_dfr(file_paths, function(path) {
  df <- read_csv(path, col_types = cols(marker = col_character(), error = col_double(), timestamp = col_double()))
  file_name <- basename(path)
  subject_id <- str_extract(file_name, "^[A-Za-z0-9]+")
  condition <- str_extract(file_name, "(Spheres|Rubber Bands|Arrows)")
  
  df %>% mutate(subject_id = subject_id, condition = condition)
})

步骤2:拟合线性混合模型

纳入条件、时间及交互作用,同时将被试设为随机效应:

lmm_full <- lmer(error ~ condition * timestamp + (1 + timestamp|subject_id), data = full_data)
summary(lmm_full)
anova(lmm_full)

三、注意事项

  • 文件名的正则表达式需根据实际命名规则调整,确保能正确提取被试ID和条件。
  • 若数据存在缺失值,记得用na.rm = TRUE处理。
  • 被试内ANOVA若不满足球形假设,aov()的结果会自动给出Greenhouse-Geisser校正值,无需额外操作。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.04 12:34:52