如何逐行统计数据框df中b1/b2/b3列元素在向量vec中的出现次数?
解决逐行统计数据框列元素在向量中的匹配次数问题
我来帮你拆解并解决这两个核心问题:
首先分析报错原因
你执行rowSums(!df[,c(b1,b2,b3)] %in% vec)时出现'x' must be an array of at least two dimensions,核心问题是提取列时丢失了二维结构:
当你用df[,c("b1","b2","b3")]提取列时,如果数据框只有一行,R会自动把它转换成一维向量,而rowSums要求输入必须是二维数组(比如数据框、矩阵)。解决这个问题的关键是加drop=FALSE参数,强制保持二维结构:df[,c("b1","b2","b3"), drop=FALSE]。
然后修正单行测试的匹配逻辑错误
你用df[1,c('b1','b2','b3')]==c(-1,-2)得到不符合预期的结果,是因为==是逐元素位置匹配,它会自动循环补齐短向量的长度:
你的目标向量c(-1,-2)长度是2,会被循环成c(-1,-2,-1),所以实际是做6==-1、-1==-2、NA==-1的比较,结果自然不对。
你需要的是判断每个元素是否存在于目标向量中,这时候应该用%in%运算符,而不是==:
df[1,c('b1','b2','b3')] %in% c(-1,-2) # 输出:FALSE TRUE NA
如果需要把NA视为"不在vec中"(即转为FALSE),可以这样处理:
res <- df[1,c('b1','b2','b3')] %in% c(-1,-2) res[is.na(res)] <- FALSE # 输出:FALSE TRUE FALSE
完整的解决方案代码
结合你的需求,下面是可以直接运行的完整流程,包含缺失值处理、逐行统计的逻辑:
1. 构造样例数据(方便测试)
# 模拟你的数据框和向量 df <- data.frame( a1 = 1:4, b1 = c(6, 2, NA, -1), b2 = c(-1, 3, -2, NA), b3 = c(NA, 4, 5, -2) ) vec <- c(-1, -2, 2)
2. 逐行统计匹配次数
# 提取b1/b2/b3列,强制保持二维结构(避免单行变向量) b_cols <- df[, c("b1", "b2", "b3"), drop = FALSE] # 生成逻辑矩阵:每个元素标记是否在vec中,NA转为FALSE(视为不在) in_vec_matrix <- apply(b_cols, MARGIN = 2, function(col) { match_res <- col %in% vec match_res[is.na(match_res)] <- FALSE match_res }) # 逐行求和,得到每行的匹配次数 df$match_count <- rowSums(in_vec_matrix)
3. 查看结果
> df a1 b1 b2 b3 match_count 1 1 6 -1 NA 1 # b2在vec中,其他不在(NA算不在) 2 2 2 3 4 1 # b1在vec中 3 3 NA -2 5 1 # b2在vec中 4 4 -1 NA -2 2 # b1和b3在vec中,符合你说的"结果为2"的场景
这个结果完全符合你的需求:
- 若b1、b2在vec而b3不在,
match_count就是2 - 若三列都不在(含缺失值),
match_count就是0
内容的提问来源于stack exchange,提问作者iago
相关产品推荐
相关产品推荐

