如何在Base R中按行统计指定列值在多列中的出现次数
用Base R统计每行指定值在多列中的出现次数
问题背景
需求:统计数据框中v1列每行的值在c1至c7列中的出现次数,新增n_v1列存储结果。
当前能手动指定单个值(如'A'、'B')完成统计,但无法批量使用v1列每行对应的值统计;尝试的代码触发警告,无法得到预期结果。
测试脚本:
# 创建数据框 c1 = c('A','B','C') c2 = c('B','B','A') c3 = c('C','C','A') c4 = c('B','C','C') c5 = c('B','A','B') c6 = c('C','B','A') c7 = c('C','B','B') v1 = c('A','C','B') df = data.frame(c1,c2,c3,c4,c5,c6,c7,v1) # 手动统计A、B、C在c1-c7列的出现次数 df$n_A = apply(df[,1:7], 1, function(x) length(which(x=='A'))) df$n_B = apply(df[,1:7], 1, function(x) length(which(x=='B'))) df$n_C = apply(df[,1:7], 1, function(x) length(which(x=='C'))) # 尝试统计v1列每行值在c1-c7列的出现次数(触发警告) df$n_v1 = apply(df[,1:7], 1, function(x) length(which(x==v1)))
执行上述尝试代码时收到警告:
longer object length is not a multiple of shorter object length
错误原因
之前的尝试代码中,apply处理每行数据x时,v1是完整的列向量(长度3),而x仅为当前行的7个元素,两者长度不匹配导致循环匹配,最终结果错误。
Base R解决方案
以下三种方法均为纯Base R实现,可批量完成统计:
方法1:遍历行索引配对取值
df$n_v1 <- sapply(1:nrow(df), function(i) { sum(df[i, 1:7] == df$v1[i]) })
通过行索引i,分别取当前行的c1-c7列数据和v1值,用sum统计匹配次数(逻辑值TRUE会被转为1,FALSE转为0,求和即得次数)。
方法2:用mapply配对行数据与v1值
df$n_v1 <- mapply(function(row_data, target_val) sum(row_data == target_val), split(df[, 1:7], 1:nrow(df)), df$v1)
将c1-c7列按行拆分为列表,再通过mapply把每行数据和对应的v1值配对传入函数,统计匹配次数。
方法3:apply遍历整行数据
df$n_v1 <- apply(df, 1, function(row) { sum(row[1:7] == row["v1"]) })
直接对整个数据框按行处理,row包含当前行的所有列值,取前7列与v1列值比较后求和。
执行任意一种方法后,df$n_v1将得到预期结果:1 3 4,分别对应每行v1值在c1-c7列中的出现次数。
内容的提问来源于stack exchange,提问作者EarthOrbGIS
相关产品推荐
相关产品推荐

