在R语言两层函数中访问非标准求值(NSE)对象的方法
在嵌套函数中传递NSE列名的解决方案
当你需要将非标准计算(NSE)的列名在主函数和其调用的子函数间共享时,直接传递原始参数会导致解析错误,比如你拆分mutate操作后出现的object 'band' not found问题。以下是两种可行的解决方法:
错误原因
在updown2中你用enquo(columnName)捕获了列名的引用,但传递给updown3时使用的是未处理的columnName,此时该参数在updown3的执行环境中无法关联到数据框的列,导致找不到对象的错误。
方法1:传递已捕获的Quosure对象
在主函数中用enquo捕获列名的引用后,直接将这个quosure对象传递给子函数,子函数无需再次捕获,直接用!!展开引用:
library(dplyr) updown2 <- function(df, columnName){ COL <- enquo(columnName) df %>% mutate(UP = toupper(!!COL)) %>% updown3(col_quosure = COL) } updown3 <- function(df, col_quosure){ df %>% mutate(DOWN = tolower(!!col_quosure)) } # 执行测试 updown2(band_members, columnName = band)
方法2:使用{{ }}(Curly-Curly)简化语法
dplyr提供的{{ }}语法可以自动完成quosure的捕获和展开,大幅简化嵌套函数的NSE参数传递:
library(dplyr) updown2 <- function(df, columnName){ df %>% mutate(UP = toupper({{ columnName }})) %>% updown3(columnName = {{ columnName }}) } updown3 <- function(df, columnName){ df %>% mutate(DOWN = tolower({{ columnName }})) } # 执行测试 updown2(band_members, columnName = band)
两种方法都能生成和你最初单层函数一致的结果:
# A tibble: 3 x 4 name band UP DOWN <chr> <chr> <chr> <chr> 1 Mick Stones STONES stones 2 John Beatles BEATLES beatles 3 Paul Beatles BEATLES beatles
内容的提问来源于stack exchange,提问作者David T
相关产品推荐
相关产品推荐

