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

如何用通用for循环生成数据框所有可能的双向列联表?

如何遍历数据框生成所有双向列联表?

问题说明

我需要遍历一个全为分类/二元因子变量的数据框,生成所有可能的双向列联表,期望效果和手动编写table(df$amazon, df$age)这类语句完全一致,但尝试的两段代码都没达到预期。

示例数据框

amazon <- c(0,1,0,1,1)
age <- c(1,2,4,3,0)
income <- c(1,1,1,0,0)
delivery <- c(1,2,0,3,4)
manhattan <- c("Manhattan", "Other", "Manhattan", "Other", "Manhattan")

df <- data.frame(cbind(amazon, age, income, delivery, manhattan))
df <- df %>% mutate(across(everything(), as.factor))

尝试过的无效代码

第一段代码(结果被合并成一个数据框,丢失独立列联表结构):

results <- data.frame()

for(i in 1:(ncol(df))){  
  for(j in (i+1):ncol(df)){
    table <- table(df[,i], df[,j], useNA = "ifany")
    results <- rbind(results,ftable(round(prop.table(table),3)))
  }
}

第二段代码(函数逻辑存在变量未定义问题):

make_p_tab <- function(x) {
  col_df <- df %>% dplyr::select(var1, all_of(x)) %>% filter(!is.na(x)) %>%
  table() %>% prop.table(.,1)
}

to_do <- function(df){
  colnames(df)
}

food_xtab <- map(to_do, make_p_tab)

解决方案

方法1:改进for循环,保留独立列联表

把每个列联表存入列表,同时可直接打印输出,完全还原手动执行的效果:

# 创建列表存储所有列联表,方便后续调用
table_list <- list()
current_index <- 1

for(i in 1:(ncol(df))){  
  for(j in (i+1):ncol(df)){
    # 获取变量名,方便识别对应关系
    var1 <- colnames(df)[i]
    var2 <- colnames(df)[j]
    # 生成双向列联表
    cross_tab <- table(df[[var1]], df[[var2]], useNA = "ifany")
    # 给列联表设置变量名标签
    dimnames(cross_tab) <- list(var1, var2)
    
    # 存入列表
    table_list[[current_index]] <- cross_tab
    # 直接打印输出,和手动执行效果一致
    cat("=== 列联表:", var1, " VS ", var2, " ===\n")
    print(cross_tab)
    cat("\n")
    
    current_index <- current_index + 1
  }
}

# 后续需要调用某张表时,直接用列表索引,比如取第1张表
# table_list[[1]]

方法2:用purrr批量生成(更简洁)

先生成所有不重复的变量对,再批量生成列联表:

library(purrr)
library(dplyr)

# 生成所有不重复的变量组合(避免重复生成A-B和B-A的表)
var_pairs <- combn(colnames(df), 2, simplify = FALSE)

# 定义生成列联表的函数
make_crosstab <- function(pair) {
  table(df[[pair[1]]], df[[pair[2]]], useNA = "ifany")
}

# 批量生成所有列联表并存储
all_tables <- map(var_pairs, make_crosstab)
# 给列表元素命名,方便识别
names(all_tables) <- map_chr(var_pairs, ~paste(.x[1], "VS", .x[2]))

# 逐个打印所有结果
walk2(all_tables, names(all_tables), function(tab, name) {
  cat("=== ", name, " ===\n")
  print(tab)
  cat("\n")
})

补充:生成比例表(行/列比例)

如果需要生成比例表,只需要在生成列联表后加上prop.table即可,比如在方法1的循环中添加:

# 生成行比例表(margin=1代表行,margin=2代表列)
prop_tab <- prop.table(cross_tab, margin = 1)
cat("=== 行比例表:", var1, " VS ", var2, " ===\n")
print(round(prop_tab, 3))
cat("\n")

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.23 19:54:59