在R中按ID分组统计非空变量并生成新列的实现方法
在R中按ID统计非空值数量并生成新列
嘿,我来帮你搞定这个问题!首先咱们先把你的示例数据转换成R里能直接用的数据框,方便测试:
# 构造你的数据集 df <- data.frame( ID = 1:5, L.NO = c(2120, 2121, 2122, 2223, 2224), Root1 = c("SX", "NC", NA, NA, NA), Root2 = c(NA, NA, NA, "CX", "SX"), Root3 = c(NA, NA, "SX", "PX", "LX"), stringsAsFactors = FALSE )
接下来,根据你的需求,我注意到你的期望输出和常规统计结果有点小矛盾(比如第4行的Root2、Root3都是非空值,按道理应该统计为2,但你期望的是1,可能是笔误?),不过我还是先给出两种常用的实现方法,你可以根据实际需求调整:
方法1:使用Base R
直接用rowSums()结合!is.na()就能快速统计每行的非NA值数量:
# 统计Root1-Root3三列的非NA值数量 df$NewCol <- rowSums(!is.na(df[, c("Root1", "Root2", "Root3")]))
运行后得到的结果:
ID L.NO Root1 Root2 Root3 NewCol 1 1 2120 SX NA NA 1 2 2 2121 NC NA NA 1 3 3 2122 NA NA SX 1 4 4 2223 NA CX PX 2 5 5 2224 NA SX LX 2
如果你是想统计除ID列外所有列的非NA值数量(这样前3行的结果就和你的期望输出一致了),代码可以改成:
# 统计除ID外所有列的非NA值数量 df$NewCol <- rowSums(!is.na(df[, -1]))
得到的结果:
ID L.NO Root1 Root2 Root3 NewCol 1 1 2120 SX NA NA 2 2 2 2121 NC NA NA 2 3 3 2122 NA NA SX 2 4 4 2223 NA CX PX 3 5 5 2224 NA SX LX 3
方法2:使用dplyr包(tidyverse风格)
如果你习惯用tidyverse的语法,这样写更直观:
library(dplyr) # 统计Root1-Root3的非NA数量 df <- df %>% rowwise() %>% mutate(NewCol = sum(!is.na(c_across(Root1:Root3)))) %>% ungroup()
要是想统计除ID外的所有列,把c_across(Root1:Root3)改成c_across(-ID)就行。
如果你的期望输出确实是第4、5行的NewCol为1,那可能还有隐藏的筛选条件(比如只统计等于某个特定值的非空值),可以补充说明,我再帮你调整代码~
内容的提问来源于stack exchange,提问作者kimi
相关产品推荐
相关产品推荐

