【问题标题】:How to extract several values from a function in a dplyr pipeline如何从 dplyr 管道中的函数中提取多个值
【发布时间】: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 个函数,每个值提取一个,但显然这并不理想。

任何建议将不胜感激。

最好的问候, 尼古拉

【问题讨论】:

    标签: r dplyr time-series tidyverse


    【解决方案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
    

    【讨论】:

      猜你喜欢
      • 2019-11-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-03-24
      • 2022-01-18
      • 1970-01-01
      • 2016-05-22
      • 2016-04-21
      相关资源
      最近更新 更多