如何结合dplyr选择器与dplyr::coalesce处理宽数据框
使用dplyr::coalesce结合选择器处理宽数据框
刚好我经常处理这类宽数据的合并需求,其实把coalesce和dplyr的选择器搭配起来非常简单,核心就是把批量选中的列传递给coalesce,让它逐行取第一个非缺失值。我给你演示两种常用的方法,结合示例数据来讲解:
首先先构造一个类似你的my_wide_data的示例(带缺失值,模拟真实场景):
library(dplyr) # 模拟你的宽数据框,包含多组前缀相同的列和其他无关列 my_wide_data <- tibble( id = 1:5, myvar1 = c(10L, NA, 11L, NA, 4L), myvar2 = c(NA, 3L, NA, 2L, NA), myvar3 = c(5L, NA, 2L, NA, 8L), unrelated_col = c("x", "y", "z", "w", "v") )
方法1:用pick() + !!!(推荐,dplyr 1.0.0+)
这是最直观的写法,pick()可以通过选择器批量选中列,!!!负责把选中的列拆成coalesce能接受的参数:
my_wide_data <- my_wide_data %>% mutate(combined_myvar = coalesce(!!!pick(starts_with("myvar"))))
方法2:用across() + purrr::reduce(更灵活)
如果你需要先对选中的列做预处理(比如类型转换),可以用across()生成列的列表,再用reduce()把coalesce应用到所有列上:
library(purrr) my_wide_data <- my_wide_data %>% mutate(combined_myvar = across(starts_with("myvar")) %>% reduce(coalesce))
验证结果
运行后查看处理好的数据:
my_wide_data #> # A tibble: 5 × 5 #> id myvar1 myvar2 myvar3 unrelated_col combined_myvar #> <int> <int> <int> <int> <chr> <int> #> 1 1 10 NA 5 x 10 #> 2 2 NA 3 NA y 3 #> 3 3 11 NA 2 z 11 #> 4 4 NA 2 NA w 2 #> 5 5 4 NA 8 v 4
可以看到combined_myvar完美提取了每行myvar前缀列的第一个非缺失值,完全符合你的需求。
注意事项
- 确保选中的列类型兼容:
coalesce要求输入列的类型可以相互转换,比如不能同时传入整数列和字符列。如果类型不一致,可以先用across(starts_with("myvar"), as.numeric)统一类型。 - 旧版dplyr兼容:如果你的dplyr版本低于1.0.0,
pick()不可用,可以换成select():coalesce(!!!select(., starts_with("myvar"))),效果完全一致。
内容的提问来源于stack exchange,提问作者joemienko
相关产品推荐
相关产品推荐

