如何用dplyr(tidyverse)不指定列名实现行式coalesce取首非缺失值
如何用dplyr(tidyverse)不指定列名对所有列执行行式coalesce操作
方法1:使用purrr::reduce结合列遍历
利用reduce函数逐列对每行执行coalesce操作,无需手动指定列名,完全贴合tidyverse风格:
library(tidyverse) df <- data.frame(x = c(NA, "s3", NA, NA,"s4"), y = c("s1", NA, "s6", "s7", "s4"), z = c("s1", NA, NA, "s7", NA)) df %>% mutate(xyz = reduce(across(everything()), coalesce))
输出结果:
x y z xyz 1 <NA> s1 s1 s1 2 s3 <NA> <NA> s3 3 <NA> s6 <NA> s6 4 <NA> s7 s7 s7 5 s4 s4 <NA> s4
方法2:rowwise()配合do.call拆分参数
如果习惯行处理逻辑,可通过c_across获取每行所有值,再用do.call将向量拆分为coalesce的独立参数:
df %>% rowwise() %>% mutate(xyz = do.call(coalesce, as.list(c_across(everything())))) %>% ungroup()
失败尝试的原因
你之前的尝试失效,是因为coalesce需要接收多个独立参数(每列对应一个参数),但c_across()返回的是单个向量,直接传入只会处理向量的第一个元素,无法实现行内多列的coalesce。而reduce会依次将前一次合并结果与下一列执行coalesce,最终得到每行第一个非缺失值;do.call则把向量转换为参数列表,让coalesce能正确处理每行的所有列值。
内容的提问来源于stack exchange,提问作者zx8754
相关产品推荐
相关产品推荐

