dplyr中mutate_at的反向操作需求:单列应用多函数或重复函数
没问题!针对你想要的「对同一列应用多个函数/重复应用同一函数」的需求,我们可以用dplyr(配合purrr处理重复场景)轻松实现,下面结合你的示例数据给你具体方案:
1. 先补全示例数据
你提供的main数据框没写完,我先补全成可直接运行的版本:
library(dplyr) main <- structure(list( PolygonId = c(0L, 1L, 1612L, 3L, 2L, 1698L), Area = c(3.018892, 1.995702, 0.582808, 1.176975, 2.277057, 0.014854), Perimeter = c(10.6415, 8.6314, 4.8478, 6.1484, 9.2226, 0.5678) ), class = "data.frame")
2. 对同一列应用多个不同函数
如果你想给Area列同时计算平方、自然对数、平方根这类不同的转换,用mutate() + across()就能搞定(dplyr 1.0.0之后推荐用across替代旧的mutate_at):
main_multi_func <- main %>% mutate( across( .cols = Area, # 指定要处理的单列 .fns = list( square = ~ .x^2, # 计算平方 natural_log = ~ log(.x),# 计算自然对数 sqrt = ~ sqrt(.x) # 计算平方根 ), .names = "{col}_{fn}" # 新列命名规则:原列名_函数名 ) ) # 查看结果 head(main_multi_func)
运行后会生成Area_square、Area_natural_log、Area_sqrt三个新列,每个列对应一种转换结果。
3. 对同一列重复应用同一个函数
如果需要重复执行同一个函数(比如多次取对数、多次累加计算),分两种场景处理:
3.1 重复次数少:手动嵌套调用
如果只需要重复2-3次,直接链式调用函数就行,写法直观:
main_repeat_simple <- main %>% mutate( Area_log1 = log(Area), # 第一次取对数 Area_log2 = log(Area_log1)# 第二次对结果再取对数 ) head(main_repeat_simple)
3.2 重复次数多:用purrr简化操作
如果需要重复5次、10次这种较多的次数,手动写太麻烦,配合purrr的accumulate()函数可以批量生成结果:
library(purrr) # 定义要重复应用的函数(这里用log为例) repeat_func <- function(x) log(x) repeat_times <- 3 # 重复3次 main_repeat_multi <- main %>% mutate( # accumulate会逐步保存每次应用后的结果 accumulate(1:repeat_times, ~ repeat_func(.x), .init = Area) %>% set_names(c("Area", paste0("Area_log", 1:repeat_times))) %>% select(-Area) # 去掉原始列,只保留重复转换后的列 ) head(main_repeat_multi)
运行后会生成Area_log1、Area_log2、Area_log3三个新列,分别对应1-3次取对数的结果。
你也可以把这个逻辑封装成自定义函数,方便后续复用:
# 封装重复应用函数的工具函数 repeat_apply <- function(col, func, n_times, prefix = "transform_") { accumulate(1:n_times, ~ func(.x), .init = col) %>% tail(n_times) %>% # 跳过原始列,只保留转换后的结果 set_names(paste0(prefix, 1:n_times)) } # 调用工具函数,对Area重复应用sqrt函数2次 main_repeat_custom <- main %>% mutate(repeat_apply(Area, sqrt, 2, prefix = "Area_sqrt")) head(main_repeat_custom)
内容的提问来源于stack exchange,提问作者anup
相关产品推荐
相关产品推荐

