如何在tidyverse中提取数据框每行最后一个非缺失值
使用tidyverse提取每行最新非缺失值的解决方案
原始数据
我们有如下数据框,其中var0/var1/var2对应同一个变量在不同时间点的测量值:
df <- data.frame(id= letters[1:5], var0= c(1:3, NA, 5), var1= c(11, NA, NA, 14:15), var2= c(NA, NA, NA, NA, 25))
原始数据结构:
id var0 var1 var2 1 a 1 11 NA 2 b 2 NA NA 3 c 3 NA NA 4 d NA 14 NA 5 e 5 15 25
需求
为每个个体(每行)提取var0到var2中最新(最右侧)的非缺失值,新增last_val列,期望输出:
id var0 var1 var2 last_val 1 a 1 11 NA 11 2 b 2 NA NA 2 3 c 3 NA NA 3 4 d NA 14 NA 14 5 e 5 15 25 25
解决方案(tidyverse实现)
方法一:按行提取最后一个非缺失值
通过rowwise()按行分组,结合c_across()提取目标列,再筛选出有效值的最后一个:
library(tidyverse) df %>% rowwise() %>% mutate(last_val = tail(na.omit(c_across(starts_with("var"))), 1)) %>% ungroup()
rowwise():将数据转为按行分组结构,确保后续操作逐行执行c_across(starts_with("var")):提取每行所有以var开头的列,组成向量na.omit():移除向量中的缺失值tail(..., 1):取处理后向量的最后一个元素(对应时间最晚的有效测量值)ungroup():取消按行分组,恢复常规数据框结构
方法二:利用coalesce反向取值
coalesce()会返回从左到右第一个非缺失值,我们先反转目标列顺序,让最新时间列排在最前,再提取:
df %>% mutate(last_val = coalesce(!!!rev(select(., starts_with("var")))))
select(., starts_with("var")):筛选所有var开头的列rev():反转列顺序(变为var2→var1→var0)!!!:将反转后的列列表展开为coalesce()的独立参数coalesce():返回第一个非缺失值,即原数据中最右侧的有效测量值
内容的提问来源于stack exchange,提问作者LulY
相关产品推荐
相关产品推荐

