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

如何统计数据框每行首个数值前的NA个数并添加为新列?

问题:统计每行首个非NA值前的NA个数并添加为新列

虚拟数据集

df <- data.frame(
  K=c(NA, NA, 3, 4,0,2,NA, NA), 
  A=c(NA, NA, NA, 4,0,3,NA, NA), 
  B=c(NA, 2, NA, NA,0,NA,NA,0), 
  C=c(0, 3, 5, NA,0,5,NA,5), 
  D=c(NA, 3, 1, 2,0,10,NA,3)
)

输出:

K  A  B  C  D
1 NA NA NA  0 NA
2 NA NA  2  3  3
3  3 NA NA  5  1
4  4  4 NA NA  2
5  0  0  0  0  0
6  2  3 NA  5 10
7 NA NA NA NA NA
8 NA NA  0  5  3

需求说明

需要为每行统计首个非NA值出现前的NA个数,并将结果作为nn列添加到数据框末尾:

  • 若行首就是非NA值,结果为0
  • 全NA行标记为1000
  • 最终期望结果:
df2 <- data.frame(
  K=c(NA, NA, 3, 4,0,2,NA, NA), 
  A=c(NA, NA, NA, 4,0,3,NA, NA), 
  B=c(NA, 2, NA, NA,0,NA,NA,0), 
  C=c(0, 3, 5, NA,0,5,NA,5), 
  D=c(NA, 3, 1, 2,0,10,NA,3),
  nn=c(3,2,0,0,0,0,1000,2)
)

输出:

K  A  B  C  D   nn
1 NA NA NA  0 NA    3
2 NA NA  2  3  3    2
3  3 NA NA  5  1    0
4  4  4 NA NA  2    0
5  0  0  0  0  0    0
6  2  3 NA  5 10    0
7 NA NA NA NA NA 1000
8 NA NA  0  5  3    2

现有代码问题

原代码:

DD<-apply(df,1,function(x) which(!is.na(x)))
unlist(map(DD, 1) , use.names=FALSE)-1

输出缺失了全NA的行:3 2 0 0 0 0 2,原因是全NA行的which(!is.na(x))返回空向量,map(DD,1)会自动忽略空元素,导致结果行数不匹配。

解决方案

1. Base R 高效向量化方案(适合大数据集)

利用向量化操作替代逐行循环,效率更高,适配20万行+500列的数据集:

# 生成每行首个非NA值的列索引
first_non_na_pos <- max.col(!is.na(df), ties.method = "first")
# 判断全NA行,赋值nn列
df$nn <- ifelse(rowSums(!is.na(df)) == 0, 1000, first_non_na_pos - 1)

2. dplyr 高效向量化方案

无需rowwise,同样用向量化操作保证效率:

library(dplyr)

df <- df %>%
  mutate(
    # 找到每行首个非NA的列索引
    first_non_na_pos = max.col(!is.na(cur_data()), ties.method = "first"),
    # 计算nn值,全NA行设为1000
    nn = ifelse(rowSums(!is.na(cur_data())) == 0, 1000, first_non_na_pos - 1)
  ) %>%
  select(-first_non_na_pos) # 可选:删除中间临时列

3. 兼容所有情况的逐行处理方案(适合小数据集)

如果需要更直观的逐行逻辑,可保留apply但处理全NA情况:

df$nn <- apply(df, 1, function(x) {
  first_idx <- which(!is.na(x))[1]
  if (is.na(first_idx)) 1000 else first_idx - 1
})

以上方案均可得到符合要求的结果,其中前两种向量化方案在大数据集上的运行效率远高于逐行循环。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.17 15:36:16