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

统计data.frame双变量组合出现次数,求Base R简洁实现方案

更简洁的Base R方法统计组合出现次数

嗨,很高兴看到你已经用嵌套循环实现了需求,不过Base R里确实有不少更简洁、易读的工具能搞定这个统计任务,下面给你分享几种常用思路:

方法一:利用table()+merge()实现左连接统计

这是最直观的方法,先统计h中所有组合的频数,再和g合并补全所有组合:

# 先给h的列改名,和g保持一致方便处理
h_named <- setNames(h, c("where", "what"))
# 统计组合频数,转成数据框
counts <- as.data.frame(table(h_named), responseName = "days")
# 左连接合并到g,保留g的所有行
g_updated <- merge(g[, c("where", "what")], counts, by = c("where", "what"), all.x = TRUE)
# 将未出现组合的频数设为0
g_updated$days[is.na(g_updated$days)] <- 0
# 还原g原来的行顺序
g_updated <- g_updated[match(paste(g$where, g$what), paste(g_updated$where, g_updated$what)), ]

table()是Base R专门用于统计分类变量组合频数的工具,转成数据框后通过merge(..., all.x = TRUE)做左连接,能确保g的所有组合都被保留,最后补0并还原顺序就和你用循环得到的结果完全一致了。

方法二:用xtabs()生成交叉表后合并

xtabs()可以直接生成交叉频数表,用法和table()类似,适合二维分类变量的统计:

h_named <- setNames(h, c("where", "what"))
# 生成交叉频数表
freq_table <- xtabs(~ where + what, data = h_named)
# 转成数据框
freq_df <- as.data.frame(freq_table, responseName = "days")
# 合并并补0
g_updated <- merge(g[, 1:2], freq_df, by = c("where", "what"), all.x = TRUE)
g_updated$days[is.na(g_updated$days)] <- 0
# 还原原顺序
g_updated <- g_updated[match(paste(g$where, g$what), paste(g_updated$where, g_updated$what)), ]

方法三:一行式赋值(最紧凑)

利用match()匹配组合字符串,直接给g$days赋值,代码更精简:

h_named <- setNames(h, c("where", "what"))
# 匹配组合并提取频数,未匹配到的设为0
g$days <- table(h_named)[match(paste(g$where, g$what), rownames(table(h_named)))]
g$days[is.na(g$days)] <- 0

table(h_named)的行名是"where.what"格式的字符串,我们用paste(g$where, g$what)生成相同格式的字符串,通过match()找到每个组合在频数表中的位置,直接提取对应数值,最后把NA替换为0即可。

为什么这些方法更好?

  • 效率更高:都是向量化操作,相比嵌套循环,当h的行数很大时,速度会快很多;
  • 可读性更强:代码逻辑清晰,一眼就能看出是在做组合频数统计,不需要理解循环里的逐行判断;
  • 可维护性好:后续如果要扩展变量,只需要修改分类变量的参数,不需要调整循环结构。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 04:04:49