条件循环统计变量组合出现次数失败,求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"))
原代码问题分析
- 拼写错误:条件判断中多次将
congruent误写为congreunt、incongruent误写为incongreunt,最后一个条件还把unimodal_preset写成unimodal,导致所有条件都无法匹配。 - 循环逻辑失效:循环变量
i(行名)和j(列名)未被使用,且直接用整列向量做判断(如di$unimodal_preset == 0返回布尔向量而非单个布尔值),逻辑完全错误。 - 赋值类型不匹配:
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
相关产品推荐
相关产品推荐

