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

条件循环统计变量组合出现次数失败,求R语言实现方案

问题描述

需根据数据集di中unimodal_preset、cong_cond、presentation_mode三个变量的取值组合,统计观测值出现次数,并填入预先构建的表格:

tab <- matrix(rep(0, times= 16), ncol= 2, byrow=TRUE)
colnames(tab) <- c('congruent', 'incongruent')
rownames(tab) <- rep(c('written', 'spoken'), 4)
tab <- as.table(tab)
tab

原编写的嵌套循环+多条件判断代码无法得到预期结果:

for (i in rownames(tab)){
  for (j in colnames(tab)){
    if (di$unimodal_preset == 0 & di$cong_cond == 'congreunt' & di$presentation_mode == 'spoken'){
      tab[i,j] <- di %>% filter(cong_cond == 'congruent' & presentation_mode == 'spoken' & unimodal_preset == 0) %>%  summarise(n = n()) %>% as.data.frame()
    } else if (di$unimodal_preset == 0 & di$cong_cond == 'congreunt' & di$presentation_mode == 'written') {
      tab[i,j] <-  di %>% filter(cong_cond == 'congruent' & presentation_mode == 'written' & unimodal_preset == 0) %>%  summarise(n = n()) %>% as.data.frame()
    } else if (di$unimodal_preset == 0 & di$cong_cond == 'incongreunt' & di$presentation_mode == 'spoken') {
      tab[i,j] <-  di %>% filter(cong_cond == 'incongruent' & presentation_mode == 'spoken' & unimodal_preset == 0) %>% summarise(n = n()) %>% as.data.frame()
    } else if (di$unimodal_preset == 0 & di$cong_cond == 'incongreunt' & di$presentation_mode == 'written') {
      tab[i,j] <-  di %>% filter(cong_cond == 'incongruent' & presentation_mode == 'written' & unimodal_preset == 0) %>%  summarise(n = n()) %>% as.data.frame()
    } else if (di$unimodal_preset == 1 & di$cong_cond == 'congreunt' & di$presentation_mode == 'spoken') {
      tab[i,j] <-  di %>% filter(cong_cond == 'congruent' & presentation_mode == 'spoken' & unimodal_preset == 1) %>%  summarise(n = n()) %>% as.data.frame()
    } else if (di$unimodal_preset == 1 & di$cong_cond == 'congreunt' & di$presentation_mode == 'written') {
      tab[i,j] <-  di %>% filter(cong_cond == 'congruent' & presentation_mode == 'written' & unimodal_preset == 1) %>%  summarise(n = n()) %>% as.data.frame()
    } else if (di$unimodal_preset == 1 & di$cong_cond == 'incongreunt' & di$presentation_mode == 'spoken') {
      tab[i,j] <-  di %>% filter(cong_cond == 'incongruent' & presentation_mode == 'spoken' & unimodal_preset == 1) %>% summarise(n = n()) %>% as.data.frame()
    } else if  (di$unimodal == 1 & di$cong_cond == 'incongreunt' & di$presentation_mode == 'written'){
      tab[i,j] <-  di %>% filter(cong_cond == 'incongruent' & presentation_mode == 'written' & unimodal_preset == 1) %>%  summarise(n = n())%>% as.data.frame()
    }
  }
}
print(tab)

使用的数据集:

> dput(head(di, 150))
structure(list(cong_cond = c("congruent", "congruent", "congruent", 
"congruent", "congruent", "congruent", "congruent", "congruent", 
"congruent", "congruent", "congruent", "congruent", "congruent", 
"congruent", "congruent", "congruent", "congruent", "congruent", 
"congruent", "congruent", "congruent", "congruent", "congruent", 
"congruent", "congruent", "congruent", "congruent", "congruent", 
"congruent", "congruent", "congruent", "congruent", "congruent", 
"congruent", "congruent", "congruent", "congruent", "congruent", 
"congruent", "congruent", "congruent", "congruent", "congruent", 
"congruent", "congruent", "congruent", "congruent", "congruent", 
"congruent", "congruent", "congruent", "congruent", "congruent", 
"congruent", "congruent", "congruent", "congruent", "congruent", 
"congruent", "congruent", "congruent", "congruent", "congruent", 
"congruent", "congruent", "congruent", "congruent", "congruent", 
"congruent", "congruent", "incongruent", "incongruent", "incongruent", 
"incongruent", "incongruent", "incongruent", "incongruent", "incongruent", 
"incongruent", "incongruent", "incongruent", "incongruent", "incongruent", 
"incongruent", "incongruent", "incongruent", "incongruent", "incongruent", 
"incongruent", "incongruent", "incongruent", "incongruent", "incongruent", 
"incongruent", "incongruent", "incongruent", "incongruent", "incongruent", 
"incongruent", "incongruent", "incongruent", "incongruent", "incongruent", 
"incongruent", "incongruent", "incongruent", "incongruent", "incongruent", 
"incongruent", "incongruent", "incongruent", "incongruent", "incongruent", 
"congruent", "congruent", "congruent", "congruent", "congruent", 
"congruent", "congruent", "congruent", "congruent", "congruent", 
"congruent", "congruent", "congruent", "congruent", "congruent", 
"congruent", "congruent", "congruent", "congruent", "congruent", 
"congruent", "congruent", "congruent", "congruent", "congruent", 
"congruent", "congruent", "congruent", "congruent", "congruent", 
"congruent", "congruent", "congruent"), presentation_mode = c("spoken", "spoken", 
"spoken", "spoken", "spoken", "spoken", "spoken", "spoken", "spoken", 
"spoken", "spoken", "spoken", "spoken", "spoken", "spoken", "spoken", 
"spoken", "spoken", "spoken", "spoken", "spoken", "spoken", "spoken", 
"spoken", "spoken", "spoken", "spoken", "spoken", "spoken", "spoken", 
"spoken", "spoken", "spoken", "spoken", "spoken", "written", 
"written", "written", "written", "written", "written", "written", 
"written", "written", "written", "written", "written", "written", 
"written", "written", "written", "written", "written", "written", 
"written", "written", "written", "written", "written", "written", 
"written", "written", "written", "written", "written", "written", 
"written", "written", "written", "written", "written", "spoken", "spoken", 
"spoken", "spoken", "spoken", "spoken", "spoken", "spoken", "spoken", 
"spoken", "spoken", "spoken", "spoken", "spoken", "spoken", "spoken", 
"spoken", "spoken", "spoken", "spoken", "spoken", "spoken", "spoken", 
"spoken", "written", "written", "written", "written", "written", 
"written", "written", "written", "written", "written", "written", 
"written", "written", "written", "written", "written", "written", 
"written", "written", "written", "written", "written", "written", 
"written", "spoken", "spoken", "spoken", "spoken", "spoken", 
"spoken", "spoken", "spoken", "spoken", "spoken", "spoken", "spoken", 
"spoken", "spoken", "spoken", "spoken", "spoken", "spoken", "spoken", 
"spoken", "spoken", "spoken", "spoken", "spoken", "spoken", "spoken", 
"spoken", "spoken", "spoken", "written", "written", "written"
), unimodal_preset = c(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 
1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0)), row.names = c(NA, -150L), class = c("tbl_df", 
"tbl", "data.frame"))
原代码问题分析
  1. 拼写错误:条件判断中多次将congruent误写为congreunt、incongruent误写为incongreunt,最后一个条件还把unimodal_preset写成unimodal,导致所有条件都无法匹配。
  2. 循环逻辑失效:循环变量i(行名)和j(列名)未被使用,且直接用整列向量做判断(如di$unimodal_preset == 0返回布尔向量而非单个布尔值),逻辑完全错误。
  3. 赋值类型不匹配:summarise返回数据框,直接赋值给表格元素会导致类型冲突,需提取具体数值。
解决方法

方法一:修复循环逻辑

修正拼写错误,利用循环变量匹配所有组合,正确定位表格位置并赋值:

# 初始化目标表格
tab <- matrix(rep(0, times= 16), ncol= 2, byrow=TRUE)
colnames(tab) <- c('congruent', 'incongruent')
rownames(tab) <- rep(c('written', 'spoken'), 4)
tab <- as.table(tab)

# 遍历unimodal_preset的两个取值(对应表格的前后两组行)
for (up in c(0, 1)) {
  # 遍历presentation_mode的两个取值
  for (pm in c('written', 'spoken')) {
    # 遍历cong_cond的两个取值
    for (cc in c('congruent', 'incongruent')) {
      # 统计当前组合的观测数
      count <- di %>% 
        filter(unimodal_preset == up, 
               presentation_mode == pm, 
               cong_cond == cc) %>% 
        nrow()
      # 确定表格行位置:up=0对应前2行,up=1对应后2行
      row_idx <- if(up == 0) which(rownames(tab) == pm) else which(rownames(tab) == pm) + 2
      # 确定表格列位置
      col_idx <- which(colnames(tab) == cc)
      # 赋值到目标表格
      tab[row_idx, col_idx] <- count
    }
  }
}

print(tab)

方法二:高效的dplyr+reshape方法

无需手动循环,直接分组统计后重塑为目标格式:

library(dplyr)
library(tidyr)

# 分组统计各组合的观测数
count_df <- di %>%
  group_by(unimodal_preset, presentation_mode, cong_cond) %>%
  summarise(n = n(), .groups = 'drop') %>%
  # 生成对应表格的行名分组标记
  mutate(row_name = presentation_mode,
         group = unimodal_preset)

# 重塑为宽表并调整行顺序匹配目标表格
result_tab <- count_df %>%
  pivot_wider(names_from = cong_cond, values_from = n, values_fill = 0) %>%
  arrange(group, row_name) %>%
  select(-group, -unimodal_preset) %>%
  column_to_rownames('row_name') %>%
  as.table()

print(result_tab)

两种方法最终输出的表格一致,针对提供的150行数据,结果示例如下:

congruent incongruent
written          60          18
spoken           57          12
written           2           6
spoken            2           3

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.20 01:30:54