在purrr与dplyr中使用NSE遇问题:数值变量处理失败求解答
在purrr与dplyr中使用非标准求值(NSE)的问题排查
我正在学习如何在purrr和dplyr函数中使用非标准求值(NSE)。案例1中对分组变量进行反引用后可以正常运行,但案例2中对数值变量反引用后运行失败,收到警告信息:argument is not numeric or logical: returning NA。
可复现代码
案例1(正常运行)
library(dplyr) library(purrr) group_var <- c("gender", "species") NSE_map_g <- map(.x = group_var, .f = ~{ starwars %>% group_by( {{.x}}) %>% summarise(mean_height = mean(height , na.rm = TRUE )) }) pluck(NSE_map_g,1)
案例2(运行失败)
num_var <- c("height", "birth_year") NSE_map_n <- map(.x = num_var, .f = ~{ starwars %>% group_by(species) %>% summarise("mean_{{.x}}" := mean({{.x}}, na.rm = TRUE )) }) pluck(NSE_map_n,1)
问题原因
案例1能正常运行是因为group_by函数对输入做了特殊处理:当传入字符串时,它会自动将字符串解析为对应的列名。但mean是基础R函数,不会做这种解析——你传入的是字符串(比如"height"),而mean()需要的是数值向量,自然会返回NA并抛出警告。
解决方法
可以通过两种方式修正案例2的代码:
方法1:使用.data代词
.data[[.x]]可以直接引用数据框中名为.x的列,不需要额外解析:
num_var <- c("height", "birth_year") NSE_map_n <- map(.x = num_var, .f = ~{ starwars %>% group_by(species) %>% summarise("mean_{{.x}}" := mean(.data[[.x]], na.rm = TRUE )) }) pluck(NSE_map_n,1)
方法2:将字符串转换为符号再反引用
用rlang::sym()把字符串转换成符号,再用!!强制反引用,让dplyr识别为列名:
num_var <- c("height", "birth_year") NSE_map_n <- map(.x = num_var, .f = ~{ var_sym <- rlang::sym(.x) starwars %>% group_by(species) %>% summarise("mean_{{.x}}" := mean(!!var_sym, na.rm = TRUE )) }) pluck(NSE_map_n,1)
内容的提问来源于stack exchange,提问作者Lulliter
相关产品推荐
相关产品推荐

