R语言如何用for循环按条件统计数据集条目并赋值到矩阵
首先你现有代码的问题主要有两个:一是矩阵赋值的索引用法错误,二维结构必须同时指定行列位置才能准确定位单元格;二是你给出的示例数据是分号拼接的单列表,需要先拆分字段才能正常统计,另外矩阵只支持存储单一数据类型,同时存条目名(字符型)和计数(数值型)会把所有内容强制转成字符串,后续做计算会出错,更推荐用数据框存储结果。
第一步:预处理原始数据
你提供的示例数据所有字段都存在同一列,用分号分隔,先拆分出标准结构化字段:
# 拆分合并列 df <- tidyr::separate(df, col = `Entry;Name;Vote`, into = c("entry", "name", "vote"), sep = ";") # 把投票列转为数值类型 df$vote <- as.numeric(df$vote)
方案1:修正后的for循环实现
之前的循环只写了单维度索引,R里矩阵/数据框是列优先存储的,单索引赋值会错位,改成明确指定行列的写法即可,另外统计计数不需要反复调用subset和count,直接对逻辑向量求和就是符合条件的行数,效率更高:
# 初始化结果数据框,直接预留你需要的其他统计列即可 result_df <- data.frame( entry_name = character(50), yes_count = numeric(50), no_count = numeric(50), other_stat1 = numeric(50), other_stat2 = numeric(50), other_stat3 = numeric(50) ) # 提取所有唯一条目 unique_entries <- unique(df$entry) for(i in seq_along(unique_entries)){ # 提取当前条目对应的所有投票记录 current_data <- df[df$entry == unique_entries[i], ] # 逐列赋值 result_df$entry_name[i] <- unique_entries[i] result_df$yes_count[i] <- sum(current_data$vote == 1) result_df$no_count[i] <- sum(current_data$vote == 0) # 其他条件的统计直接在这里追加即可,比如: # result_df$other_stat1[i] <- sum(current_data$name == "Tom") }
方案2:无循环高效分组统计
如果所有统计都是按条目维度聚合,直接用分组统计写法更简洁,运行速度也比手写for循环快,不需要提前初始化结果结构:
# 基础R实现 result <- aggregate(vote ~ entry, data = df, FUN = function(x) c(yes = sum(x==1), no = sum(x==0))) # dplyr实现,扩展其他统计项更灵活 library(dplyr) result <- df %>% group_by(entry) %>% summarise( yes_count = sum(vote == 1), no_count = sum(vote == 0), # 其他统计项直接追加即可 # total_vote = n(), # user_count = n_distinct(name) )
注意事项
- 不要用单索引给二维结构赋值,R会默认把二维结构按列拉成一维向量再定位位置,极易出现赋值错位的问题。
- 统计符合条件的行数优先用
sum(逻辑判断)写法,比反复调用subset()+count()少了多次数据拷贝的开销,速度更快。 - 混合存储字符、数值类型的结果不要用矩阵,用数据框或者tibble才不会出现类型强制转换的问题。
内容的提问来源于stack exchange,提问作者osamurak
相关产品推荐
相关产品推荐

