You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在R中按条件统计有效响应数并生成新列?

高效统计tibble每行有效响应数(排除4和NA)

需求明确:给tibble数据框新增一列sum,统计每行中既不是NA也不等于4的数值个数,其余情况(值为4或NA)不计入统计。

测试数据

library(tibble)
id <- c("agb", "efr", "h3z", "h8r", "p9o", "tr5", "g1f", "l95" )
c1 <- c(1:3, NA, 4, 9, 4, 4)
c2 <- c(9, 4, 2, 2, 2, 7, 6, 5)
c3 <- c(1, 1, 1, NA, NA, 3, 3, 4)
c4 <- c(1, 1, 1, NA, NA, 3, 3, 4)
DF <- tibble(id, c1, c2, c3, c4)

方法一:向量化rowSums(最高效,适合大数据集)

利用R的向量化运算直接批量处理整列,避免循环或逐行判断,效率远超ifelse:

library(dplyr)
DF2 <- DF %>%
  mutate(sum = rowSums(!is.na(.[, -1]) & .[, -1] != 4))

解释:

  • .[, -1]:排除第一列id,只处理数值列
  • !is.na(...):筛选非NA的值
  • ... != 4:筛选不等于4的值
  • rowSums:对每行的符合条件的标记(TRUE=1,FALSE=0)求和

如果需要指定具体列(而非排除第一列),可以写成:

DF2 <- DF %>%
  mutate(sum = rowSums(!is.na(select(., c1:c4)) & select(., c1:c4) != 4))

方法二:dplyr + across(可读性优先)

如果更习惯dplyr的列遍历语法,用across指定目标列,再求和:

library(dplyr)
DF2 <- DF %>%
  mutate(sum = rowSums(across(c1:c4, ~ !is.na(.x) & .x != 4)))

验证结果

运行上述代码后,DF2的sum列完全符合期望:

# 输出DF2
DF2
#> # A tibble: 8 × 6
#>   id       c1    c2    c3    c4   sum
#>   <chr> <dbl> <dbl> <dbl> <dbl> <dbl>
#> 1 agb       1     9     1     1     4
#> 2 efr       2     4     1     1     3
#> 3 h3z       3     2     1     1     4
#> 4 h8r      NA     2    NA    NA     1
#> 5 p9o       4     2    NA    NA     1
#> 6 tr5       9     7     3     3     4
#> 7 g1f       4     6     3     3     3
#> 8 l95       4     5     4     4     1

为什么nrow、length没用?

nrow是统计数据框的总行数,length是统计单个向量的元素个数,都不是针对每行元素的条件统计,所以无法满足需求;而ifelse需要逐个列判断,当列数多的时候会非常繁琐,以上两种方法都是批量处理,代码简洁且效率高。

内容的提问来源于stack exchange,提问作者Laura31

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.07 05:20:18