R语言:计算数据框两列数值的跨列出现次数及频率列
统计DataFrame中数值在两列的总出现次数并添加频率列
需求
给目标DataFrame添加以下列:
count1:对应行col1数值在col1和col2两列中的总出现次数count2:对应行col2数值在col1和col2两列中的总出现次数Freqcol1:count1占两列总元素数的比例(总元素数=行数×2)Freqcol2:count2占两列总元素数的比例
原始数据
ID col1 col2 1 10 12 2 10 15 3 10 10
期望输出
ID col1 col2 count1 count2 Freqcol1 Freqcol2 1 10 12 4 1 0.66 0.16 2 10 15 4 1 0.66 0.16 3 10 10 4 4 0.66 0.66
你的代码问题
你提供的代码存在三个核心问题:
- 仅统计了数值在单列的出现次数,没有合并两列计算总次数
- 变量名错误:定义了
count1却调用了未定义的count_col1 - 未实现频率列的计算逻辑
正确解决方案
方法1:基础R实现
# 构造原始数据框 mydata <- data.frame( ID = 1:3, col1 = c(10, 10, 10), col2 = c(12, 15, 10) ) # 统计两列所有数值的总出现次数 total_counts <- table(c(mydata$col1, mydata$col2)) # 添加count1、count2列:匹配每行col1/col2对应的总次数 mydata$count1 <- total_counts[as.character(mydata$col1)] mydata$count2 <- total_counts[as.character(mydata$col2)] # 计算频率:总元素数为行数×2 total_elements <- nrow(mydata) * 2 mydata$Freqcol1 <- round(mydata$count1 / total_elements, 2) mydata$Freqcol2 <- round(mydata$count2 / total_elements, 2) # 查看结果 print(mydata)
方法2:dplyr简洁实现(需要加载tidyverse包)
library(dplyr) library(tidyr) # 构造原始数据框 mydata <- data.frame( ID = 1:3, col1 = c(10, 10, 10), col2 = c(12, 15, 10) ) # 生成所有数值的总次数表 total_counts <- mydata %>% pivot_longer(cols = c(col1, col2), values_to = "value") %>% count(value, name = "total") # 匹配次数并计算频率 mydata <- mydata %>% left_join(total_counts, by = c("col1" = "value")) %>% rename(count1 = total) %>% left_join(total_counts, by = c("col2" = "value")) %>% rename(count2 = total) %>% mutate( total_elements = n() * 2, Freqcol1 = round(count1 / total_elements, 2), Freqcol2 = round(count2 / total_elements, 2) ) %>% select(ID, col1, col2, count1, count2, Freqcol1, Freqcol2) # 查看结果 print(mydata)
结果说明
运行代码后输出与期望一致(注:round保留两位小数时,0.666...会显示为0.67,若需与示例完全一致,可调整为format(x, nsmall = 2)或直接保留更多小数后截取)。
内容的提问来源于stack exchange,提问作者akang
相关产品推荐
相关产品推荐

