如何在R语言中将数据框转换为类对比计数矩阵?
实现DataFrame转累计计数的宽格式列
我刚好处理过类似的需求,要把包含重复code的DataFrame转换成每个code列显示累计出现次数的宽格式(就像你给出的示例那样),用R语言的tidyverse工具包可以轻松实现,下面是具体的方法:
1. 先模拟你的示例数据
code <- data.frame(code = c('R1111', 'R1112', 'R1111', 'R1111', 'R1113', 'R1112', 'R1112', 'R1112', 'R1113', 'R1115'))
2. 核心实现代码(tidyverse版本)
这个方法简洁直观,处理1400行数据完全没有压力:
library(dplyr) library(tidyr) # 生成结果数据框 result_df <- code %>% # 按code分组,计算每组内的累计出现次数 group_by(code) %>% mutate(count = row_number()) %>% # 转成宽格式,缺失值填充为0 pivot_wider( names_from = code, # 用code值作为新列名 values_from = count, # 用累计计数作为列值 values_fill = 0 # 没有值的位置填0 ) %>% # 保留原始的code列并调整顺序 mutate(original_code = code$code) %>% select(original_code, everything()) %>% rename(code = original_code) # 查看结果 print(result_df)
3. 代码解释
group_by(code):把数据按code值分组,这样后续的计数是每组内的累计次数,而不是全局计数。mutate(count = row_number()):为每个分组生成从1开始的序号,对应code第几次出现。pivot_wider(...):将长格式数据转为宽格式,自动生成每个code对应的列,values_fill=0确保非当前code的列都显示0。- 最后几步是为了把原始的code列放回结果的第一列,和你给出的示例结构完全匹配。
4. Base R替代方案(无需加载包)
如果你不想用tidyverse,也可以用base R实现:
# 生成每组的累计计数 code$count <- ave(rep(1, nrow(code)), code, FUN = cumsum) # 转换为宽格式 wide_data <- reshape(code, idvar = seq(nrow(code)), timevar = "code", direction = "wide") # 清理列名并填充NA为0 colnames(wide_data) <- gsub("count\\.", "", colnames(wide_data)) wide_data[is.na(wide_data)] <- 0 # 合并原始code列并整理结果 result_df <- cbind(code = code$code, wide_data) result_df <- result_df[, !colnames(result_df) %in% "seq(nrow(code))"] print(result_df)
两种方法都能得到你想要的结果,处理1400行数据速度都很快,推荐用tidyverse版本,代码可读性更强。
内容的提问来源于stack exchange,提问作者user6401955
相关产品推荐
相关产品推荐

