如何在R中索引B、C、D列的非NA值并生成指定新数据框
搞定你的R数据框处理需求
嘿,我来帮你一步步解决这两个问题:
1. 正确获取B、C、D列非NA值对应的行索引
你之前踩的坑是is.na()只能接受一个输入,不能直接塞多列进去。咱们分两种情况来处理:
如果要的是「至少有一列(B/C/D)非NA」的行索引(对应后续生成df2的核心需求)
这个是最实用的方案,用rowSums判断每行是否存在非NA值,再提取对应的行号:
# 提取B、C、D列,判断每行是否有非NA值,返回符合条件的行索引 valid_rows <- which(rowSums(!is.na(df[, c("B", "C", "D")])) > 0) valid_rows
运行后会得到 [1] 2 3 4 5 6 7 8 9,这正好是你要的df2对应的原数据行号。
如果确实需要生成你给出的重复索引列表
要是你真的需要那种每行符合条件就重复出现两次的索引格式,可以用rep()快速实现:
# 把符合条件的行索引重复两次,转成数据框格式 repeat_indices_df <- data.frame(V1 = rep(valid_rows, each = 2)) repeat_indices_df
输出结果就和你期望的几乎一致(除了开头的1,因为原数据行1的B/C/D全是NA,不符合条件,应该是你不小心写错啦):
V1 1 2 2 2 3 3 4 3 5 4 6 4 7 5 8 5 9 6 10 6 11 7 12 7 13 8 14 8 15 9 16 9
2. 生成目标数据框df2
有了上面的valid_rows,子集化操作就非常简单了:
# 提取符合条件的行 df2 <- df[valid_rows, ] # 可选:把A列里的字符串"NA"转换成真正的NA值(和你给出的目标df2完全匹配) df2$A[df2$A == "NA"] <- NA # 查看最终结果 print(df2)
运行后得到的df2完全符合你的预期:
A B C D E 2 b 2 9 1 2 3 c 3 8 2 3 4 d 4 4 3 4 5 e NA 5 NA 5 6 f NA 7 5 6 7 g 5 5 NA 7 8 NA 6 6 7 8 9 h 8 NA 8 9
如果你习惯用tidyverse的语法,用dplyr写会更直观易懂:
library(dplyr) df2 <- df %>% # 筛选出B/C/D至少有一个非NA的行 filter(rowSums(!is.na(across(c(B, C, D)))) > 0) %>% # 把A列的"NA"字符串转成真正的NA mutate(A = na_if(A, "NA"))
结果和基础R方法完全一致哦。
内容的提问来源于stack exchange,提问作者vcat
相关产品推荐
相关产品推荐

