如何从 dplyr 管道中的函数中提取多个值
Posted
技术标签:
【中文标题】如何从 dplyr 管道中的函数中提取多个值【英文标题】:How to extract several values from a function in a dplyr pipeline 【发布时间】:2021-11-15 18:34:47 【问题描述】:有没有一种好方法来创建一个 dplyr 管道,其中 mutate 在一个步骤中从一个函数中提取几列?例如,假设您有一个这样的数据框:
x y
1 5
2 3
6 4
你有一个函数可以返回总和和乘积:
sum_and_product <- function(x, y) list(sum=x+y,product=x*y)
那么如何创建一个管道来生成原始数据帧,该数据帧由一次调用计算的 sum 和 product 列丰富?比如:
df %>% mutate_multiple(c(sum, product)=sum_and_product(x, y))
x y sum product
1 5 6 5
2 3 5 6
6 4 10 24
如果这不能通过 dplyr 管道完成,还有哪些其他替代方案?
为了让您更好地了解我在实际使用案例中想要实现的目标:我需要计算存储在单个数据框中的多个时间序列的结构变化点。当我只计算中断发生的时间时,我可以非常简单有效地做到这一点:
df %>% group_by(timeseries_id) %>% mutate(cpt = my.cpt(time, value))
但问题是,cpt 必须返回 3 个值而不仅仅是一个(更改的时间、之前的值和之后的值),这会破坏一切。当我使用循环执行此操作时,它非常缓慢(而且也很丑陋)。我想我可以编写 3 个函数,每个值提取一个,但显然这并不理想。
任何建议将不胜感激。
最好的问候, 尼古拉
【问题讨论】:
【参考方案1】:将您的函数从 list
更改为 data.frame
即可,即
library(dplyr)
sum_and_product <- function(x, y) data.frame(sum=x+y,product=x*y)
df %>%
mutate(sum_and_product(x, y))
# x y sum product
#1 1 5 6 5
#2 2 3 5 6
#3 6 4 10 24
【讨论】:
谢谢,这正是我想要的!【参考方案2】:您可以将sum_and_product
的输出保存为列表,然后使用unnest_wider
从中获取不同的列。
library(dplyr)
library(tidyr)
sum_and_product <- function(x, y) list(sum=x+y,product=x*y)
df %>%
rowwise() %>%
mutate(z = list(sum_and_product(x, y))) %>%
unnest_wider(z)
# x y sum product
# <int> <int> <int> <int>
#1 1 5 6 5
#2 2 3 5 6
#3 6 4 10 24
【讨论】:
以上是关于如何从 dplyr 管道中的函数中提取多个值的主要内容,如果未能解决你的问题,请参考以下文章