R中curly curly运算符与map()结合使用失效问题排查
问题分析与解决
核心问题
你遇到的两个问题本质都是参数传递类型不匹配:curly curly({{}})运算符需要接收**列名符号(symbol)**而非列的数值向量,同时pmap()的用法存在逻辑错误。
1. map()调用失效原因
当前map(mtcars %>% select_if(is.numeric), ~mean_by(mtcars,cyl,.))中,.传递的是列的数值向量(比如mtcars$mpg的具体值),而非列名符号。{{conti}}需要的是能在data环境中解析的列引用,直接传向量会导致函数无法正确识别要计算的列。
2. pmap()报错原因
pmap()用于多参数并行迭代,输入需为参数列表(每行对应一组参数),但你直接传入mtcars的数值列,相当于把每一行数据当成参数传递,完全不符合需求。另外,直接写cyl会让R在全局环境查找该对象,而非作为mtcars的列符号传递,因此报object 'cyl' not found。
解决方法
方法一:修正map()调用(推荐)
先提取数值列的列名字符串,再将字符串转换为符号传递给mean_by:
library(tidyverse) mean_by <- function(data,by,conti){ data %>% group_by({{by}}) %>% summarise(mean=mean({{conti}})) %>% print() %>% ggplot(aes(x={{by}},y=mean))+geom_col() } # 获取数值列的列名 numeric_col_names <- mtcars %>% select_if(is.numeric) %>% colnames() # 遍历列名,用!!sym()将字符串转为符号 map(numeric_col_names, ~mean_by(mtcars, cyl, !!sym(.x)))
方法二:修改函数支持字符串输入
如果想直接传列名字符串,可调整函数用ensym()将字符串转为符号:
mean_by <- function(data,by,conti){ by <- ensym(by) conti <- ensym(conti) data %>% group_by({{by}}) %>% summarise(mean=mean({{conti}})) %>% print() %>% ggplot(aes(x={{by}},y=mean))+geom_col() } # 直接传列名字符串即可 map(numeric_col_names, ~mean_by(mtcars, "cyl", .x))
方法三:正确使用pmap()(仅多参数迭代时需用)
若确实需要用pmap,需构造正确的参数列表,每行对应一组要传递给mean_by的参数:
# 构造参数数据框:data固定为mtcars,by固定为cyl,conti为所有数值列的符号 params <- tibble( data = list(mtcars), by = list(quote(cyl)), conti = syms(numeric_col_names) ) pmap(params, mean_by)
验证逻辑
单独调用mean_by(mtcars,cyl,carb)能正常工作,是因为你直接传递了列名符号cyl和carb,符合{{}}的参数要求,而迭代时错误传递了列值而非符号。
内容的提问来源于stack exchange,提问作者Yann peacelover
相关产品推荐
相关产品推荐

