如何在dplyr pipeline中通过单步mutate从自定义函数提取多列结果
在dplyr管道中单步提取自定义函数多列返回值的解决方案
dplyr 1.0.0及以上版本原生支持该需求,无需自定义特殊函数,以下是不同场景的实现方式:
示例场景实现
你的示例数据和自定义函数如下:
library(dplyr) library(tidyr) df <- tibble(x = c(1,2,6), y = c(5,3,4)) sum_and_product <- function(x, y) list(sum=x+y,product=x*y)
最简写法
当自定义函数返回的每个元素长度等于输入行数时,直接在mutate中调用函数即可:
df %>% mutate(sum_and_product(x, y))
输出结果完全符合预期:
# A tibble: 3 × 4 x y sum product <dbl> <dbl> <dbl> <dbl> 1 1 5 6 5 2 2 3 5 6 3 6 4 10 24
通用兼容写法
适配所有场景,包括分组后单组返回一组结果的情况:
df %>% mutate(res = purrr::pmap(list(x, y), sum_and_product)) %>% unnest_wider(res)
分组结构变点业务场景实现
针对你需要按时间序列ID分组计算结构变点的需求,只需保证你的my.cpt函数返回命名列表,写法如下:
# 示例my.cpt返回结构,只需和你实际返回的命名对应即可 my.cpt <- function(time, value) { # 原有计算逻辑保留 list(cpt_time = 突变发生时间, pre_value = 突变前数值, post_value = 突变后数值) } # 管道操作代码 df %>% group_by(timeseries_id) %>% mutate(cpt_res = list(my.cpt(time, value))) %>% unnest_wider(cpt_res) %>% ungroup() # 不需要保留分组时可加上
如果你使用的是dplyr 1.1.0及以上版本,可以用更接近你预期的多赋值语法,无需调用unnest:
df %>% mutate( c(cpt_time, pre_value, post_value) := my.cpt(time, value), .by = timeseries_id )
内容的提问来源于stack exchange,提问作者Nikolai
相关产品推荐
相关产品推荐

