在purrr中处理嵌套/非嵌套列时map多模型的函数故障排查
嵌套模型分析:动态列函数错误修正
问题根源
make_data_input里的max计算用了字符串字面量"{{x}}_cumsum",没有正确引用新生成的累计和列,导致取到的是字符串本身而非列值的最大值。- 嵌套调用
map2时,错误地直接写price,没有用.y传递动态参数,导致函数无法识别要处理的列。
修正步骤
1. 修复make_data_input函数
把max部分的字符串引用改成直接调用新生成的列,用tidyeval的正确语法:
make_data_input <- function(df, x) { df %>% mutate( "{{x}}_cumsum" := cumsum({{x}}), "max_{{x}}_cumsum" := max({{x}}_cumsum) # 直接引用累计和列,不用加引号 ) }
这样就能正确计算累计和列的最大值,而非取字面量。
2. 修复嵌套数据集的调用
原来的map2传参错误,要把price作为字符串列传递,并用.y引用:
diamonds %>% group_by(cut, color) %>% nest() %>% mutate( test = list(selected_cols), carat = "carat", price_col = "price" # 把price列名存为字符串 ) %>% mutate( simple = map(data, make_data_fixed), calculate_direct = map2(data, test, calculate_stuff), calculate_indirect = map2(data, carat, calculate_stuff), complex = map2(data, price_col, ~make_data_input(df = .x, x = .y)) # 用.y传递动态参数 )
完整可运行代码
library(tidyverse) # 固定参数函数(正常运行) make_data_fixed <- function(df) { df %>% mutate( price_cumsum = cumsum(price), max_price_cumsum = max(price_cumsum) ) } # 修正后的动态参数函数 make_data_input <- function(df, x) { df %>% mutate( "{{x}}_cumsum" := cumsum({{x}}), "max_{{x}}_cumsum" := max({{x}}_cumsum) ) } selected_cols <- c("clarity","depth") # 动态列表列函数(正常运行) calculate_stuff <- function(df, x) { df %>% summarize(across(all_of(x), ~length(unique(.)))) } # 测试非嵌套调用 calculate_stuff(diamonds, selected_cols) make_data_input(diamonds, "price") # 现在非嵌套也能正常工作 # 修正后的嵌套数据处理 diamonds %>% group_by(cut, color) %>% nest() %>% mutate( test = list(selected_cols), carat = "carat", price_col = "price" ) %>% mutate( simple = map(data, make_data_fixed), calculate_direct = map2(data, test, calculate_stuff), calculate_indirect = map2(data, carat, calculate_stuff), complex = map2(data, price_col, ~make_data_input(df = .x, x = .y)) )
关键注意点
- Tidyeval语法中,
{{x}}用来引用函数参数对应的列,生成新列名用"{{x}}_cumsum" :=格式;引用新生成的列时直接写{{x}}_cumsum即可,不需要加引号。 - 嵌套数据传参时,
map2的.y要传字符串形式的列名(和carat列保持一致),不能直接写列名裸词,否则会被当作全局变量处理。
内容的提问来源于stack exchange,提问作者alejandro_hagan
相关产品推荐
相关产品推荐

