Dplyr/tidyverse报错:rename_at的.funs需含单个重命名函数而非多个
问题描述
我有如下测试数据:
library(tidyverse) df <- tibble( g1 = c(1, 1, 2, 2, 2), g2 = c("a", "a", "a", "b", "b"), # 注意原代码中字符串未加引号,这里修正避免报错 a = sample(5), b = sample(5) )
我希望编写一个函数对分组列进行均值汇总,并将结果列前缀设置为"mean_",编写的函数如下:
my_summarise1 <- function(df, group_var, summarise_var) { df %>% group_by_at(.vars = group_var) %>% summarise_at(.vars = summarise_var, .funs= mean) %>% rename_at(.vars= summarise_var, .funs=paste('mean_', .)) }
移除rename_at语句时函数可正常运行,但添加后执行my_summarise1(df, vars(g1,g2),vars(a,b))会报错:
Error: `.funs` must contain one renaming function, not 4
请问如何有效给新列名添加前缀?另外一个小问题:调用函数时能否避免使用vars()或给列名加引号?
解决方案
一、给汇总列添加"mean_"前缀的正确方法
你遇到的报错是因为rename_at的.funs参数需要接收一个函数,直接写paste('mean_', .)的写法不符合要求——这里的.会被识别为当前列名,但paste本身不是返回函数的正确写法。下面两种方法都能解决这个问题:
方法1:修正rename_at的写法
用公式语法(~)把paste包装成匿名函数,明确告诉dplyr如何处理列名:
my_summarise1 <- function(df, group_var, summarise_var) { df %>% group_by_at(.vars = group_var) %>% summarise_at(.vars = summarise_var, .funs = mean) %>% rename_at(.vars = summarise_var, .funs = ~paste('mean_', ., sep = "")) # sep参数避免列名出现空格 }
方法2:改用rename_with(推荐,dplyr 1.0.0+版本标准写法)
rename_with是dplyr更新后推荐的重命名函数,语法更直观:
my_summarise1 <- function(df, group_var, summarise_var) { df %>% group_by_at(.vars = group_var) %>% summarise_at(.vars = summarise_var, .funs = mean) %>% rename_with(.fn = ~paste('mean_', ., sep = ""), .cols = summarise_var) }
测试调用后,就能得到带mean_前缀的汇总列了。
二、避免使用vars()或引号调用函数
可以利用dplyr的**tidy评估(tidy evaluation)**特性,让函数支持直接传入裸列名(不用vars()或引号),甚至能省掉重命名的步骤,写法更简洁:
改进后的函数(支持裸列名)
my_summarise2 <- function(df, ..., summarise_var) { df %>% group_by(...) %>% # ... 接收任意数量的分组裸列名 # 用across的.names参数直接指定列名格式,{.col}会替换成原列名 summarise(across({{ summarise_var }}, mean, .names = "mean_{.col}")) }
调用方式(直接传裸列名)
# 单个汇总变量 my_summarise2(df, g1, g2, summarise_var = a) # 多个汇总变量,用c()包裹 my_summarise2(df, g1, g2, summarise_var = c(a, b))
这里的核心技巧:
...用来接收任意数量的分组变量,直接传裸列名即可;{{ summarise_var }}是大括号语法,用来捕获用户传入的裸列名(单个或多个用c()包裹);across的.names参数可以直接定义输出列名的模板,连额外的重命名步骤都省了,非常高效。
内容的提问来源于stack exchange,提问作者Jacek Kotowski
相关产品推荐
相关产品推荐

