如何让tidyr::complete在重复嵌套同一列时正常工作?
解决complete函数中nesting重复列名的问题
当complete()的nesting()参数中传入重复列名时,tidyverse会自动给重复列添加后缀(如cyl...1、cyl...2),但原数据不存在这些带后缀的列,进而触发full_join()的匹配错误。要避免报错且不生成重复列,核心是确保传给nesting()的列名唯一,以下是几种优雅的处理方式:
1. 自定义函数内统一处理(推荐)
如果是在自定义函数中接收可能重复的列参数,先捕获列名符号并去重,再传入nesting():
library(tidyverse) safe_complete <- function(data, nesting_cols, fill_cols) { # 捕获列名符号并去重 unique_nesting_syms <- unique(ensyms(nesting_cols)) data %>% complete(nesting(!!!unique_nesting_syms), {{fill_cols}}) } # 测试重复列场景 mtcars %>% safe_complete(cyl, cyl, vs)
2. 直接调用时去重列名
如果是单次调用时遇到重复列,直接在nesting()内部处理:
# 符号形式传参时去重 mtcars %>% complete(nesting(!!!unique(ensyms(cyl, cyl))), vs) # 字符向量形式传参时去重 nesting_cols <- c("cyl", "cyl") mtcars %>% complete(nesting(!!!syms(unique(nesting_cols))), vs)
原理说明
ensyms()会将传入的列名转为符号列表,unique()去除重复的符号后,用!!!(非拼接操作符)将符号列表展开传入nesting(),确保nesting()只接收唯一列名,既不会触发后缀命名,也能正常匹配原数据列。
内容的提问来源于stack exchange,提问作者Julien
相关产品推荐
相关产品推荐

