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

R语言中数据框子集多组加权t检验的报错排查

问题描述

我正在R中编写代码,想要对数据框的不同子集执行多组加权t检验,初始代码如下:

library(weights)

group_list <- list(unique(df$group))

t_tests <- for (g in group_list){wtd.t.test(x=df[df$group == g,]$var2[df[df$group == g,]$var1=="A"],y=df[df$group == g,]$var2[df[df$group == g,]$var1=="B"],
weight=df[df$group == g,]$weight[df[df$group == g,]$var1=="A"],weighty=df[df$group == g,]$weight[df[df$group == g,]$var1=="B"],samedata=FALSE)}

其中var2是关注的结果变量,我希望检验var1="A"和var1="B"的均值差异显著性,并针对group变量的不同取值对每个数据子集执行该检验。

运行上述代码时出现错误:

Error in wtd.t.test(x = df[df$group == g,  :  object 'out' not found

想确认是不是函数结构有误?该如何实现对数据框每个子集执行加权t检验?

更新1:尝试嵌套tibbles方法

改用tidyverse的嵌套数据框方法,代码如下:

library(weights)
library(tidyverse)

df %>% 
  nest(-group) %>% 
  mutate(fit = map(data, ~ wtd.t.test(x=.%>%filter(var1 == "A")$var2,y=.%>% filter(var1 == "B")$var2,
weight=.%>% filter(var1 == "A")$weight,weighty=.%>% filter(var1 == "B")$weight,samedata=FALSE)),
         results = map(fit, glance)) %>% 
  unnest(results)

报错信息:

Error in `mutate()`:
ℹ In argument: `fit = map(...)`.
Caused by error in `map()`:
ℹ In index: 1.
Caused by error in `weight / mean(weight, na.rm = TRUE)`:
! non-numeric argument to binary operator
Backtrace:
  1. ... %>% unnest(results)
 10. purrr::map(...)
 11. purrr:::map_("list", .x, .f, ..., .progress = .progress)
 15. .f(.x[[i]], ...)
 16. weights::wtd.t.test(...)

除Var1外所有变量均为数值型,Var1不参与计算,不清楚为何出现该错误,求解决方案。

若将代码改写为:

df %>% 
  nest(-country) %>% 
  mutate(fit = map(data, ~ wtd.t.test(x=filter(.,var1 == "A")$var2,y=filter(.,var1 == "B")$var2,
weight=filter(.,var1 == "A")$weight,weighty=filter(.,var1 == "B")$weight,samedata=FALSE)),
         results = map(fit, glance)) %>% 
  unnest(results)

报错变为:

Error in `mutate()`:
ℹ In argument: `fit = map(...)`.
Caused by error in `map()`:
ℹ In index: 1.
Caused by error in `wtd.t.test()`:
! object 'out' not found
Backtrace:
  1. ... %>% unnest(results)
 10. purrr::map(...)
 11. purrr:::map_("list", .x, .f, ..., .progress = .progress)
 15. .f(.x[[i]], ...)
 16. weights::wtd.t.test(...)

更新2:可复现代码示例

用mtcars数据集测试的代码如下:

library(weights)
library(tidyverse)

mtcars %>% 
  nest(-cyl) %>% 
  mutate(fit = map(data, ~ wtd.t.test(x=.%>%filter(gear == 3)$disp,y=.%>% filter(gear = 4)$disp,
weight=.%>% filter(gear == 3)$wt,weighty=.%>% filter(gear == 4)$wt,samedata=FALSE)),
         results = map(fit, glance)) %>% 
  unnest(results)

改写后的代码:

mtcars %>% 
  nest(-cyl) %>% 
  mutate(fit = map(data, ~ wtd.t.test(x=filter(.,gear == 3)$disp,y=filter(.,gear == 4)$disp,
weight=filter(.,gear == 3)$weight,weighty=filter(.,gear == 4)$weight,samedata=FALSE)),
         results = map(fit, glance)) %>% 
  unnest(results)

解决方案

1. 初始循环代码的修正

  • group_list <- list(unique(df$group))会把整个分组向量塞进一个列表元素,导致循环仅执行一次,应改为group_list <- unique(df$group)直接遍历分组值。
  • 循环无法直接赋值给变量,需预先创建列表存储每个检验结果。

修正后的循环代码:

library(weights)

group_list <- unique(df$group)
t_tests <- list()

for (g in group_list) {
  # 提取当前分组的子集
  sub_df <- df[df$group == g, ]
  # 分别筛选A和B组的数据
  a_data <- sub_df[sub_df$var1 == "A", ]
  b_data <- sub_df[sub_df$var1 == "B", ]
  
  # 执行加权t检验,跳过空子集避免报错
  if (nrow(a_data) > 0 && nrow(b_data) > 0) {
    t_tests[[as.character(g)]] <- wtd.t.test(
      x = a_data$var2,
      y = b_data$var2,
      weight = a_data$weight,
      weighty = b_data$weight,
      samedata = FALSE
    )
  }
}

# 查看结果
t_tests

2. 嵌套tibbles方法的修正

核心问题:

  • 管道语法错误:.%>%filter(...)写法无效,应使用filter(., ...);
  • 变量名不匹配:mtcars中无weight变量,需用wt;
  • broom::glance()不支持weights::wtd.t.test返回对象,需手动提取结果。

修正后的嵌套代码:

library(weights)
library(tidyverse)

# 定义提取加权t检验结果的函数
extract_wtd_t_result <- function(test_obj) {
  if (is.null(test_obj)) {
    return(tibble(mean_x = NA, mean_y = NA, t_stat = NA, df = NA, p_value = NA, se_diff = NA))
  }
  tibble(
    mean_x = test_obj$additional[["mean.x"]],
    mean_y = test_obj$additional[["mean.y"]],
    t_stat = test_obj$coefficients[["t.value"]],
    df = test_obj$coefficients[["df"]],
    p_value = test_obj$coefficients[["p.value"]],
    se_diff = test_obj$coefficients[["Std. Error"]]
  )
}

# mtcars测试的修正代码
mtcars %>% 
  nest(data = -cyl) %>% 
  mutate(
    fit = map(data, function(sub_df) {
      a_data <- filter(sub_df, gear == 3)
      b_data <- filter(sub_df, gear == 4)
      
      # 跳过空子集
      if (nrow(a_data) == 0 || nrow(b_data) == 0) {
        return(NULL)
      }
      
      wtd.t.test(
        x = a_data$disp,
        y = b_data$disp,
        weight = a_data$wt,
        weighty = b_data$wt,
        samedata = FALSE
      )
    }),
    results = map(fit, extract_wtd_t_result)
  ) %>% 
  unnest(results)

关键注意事项

  • 确保每个分组下var1="A"和var1="B"都有有效数据,否则需添加判断跳过空子集;
  • weights::wtd.t.test返回的对象结构特殊,无法直接用broom系列函数解析,需手动提取统计量;
  • 变量名需严格匹配数据集,避免出现“变量不存在”的隐性错误。

内容的提问来源于stack exchange,提问作者flâneur

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.20 17:35:11