R dplyr:将列表输出写入数据框

4
假设我有以下函数:
SlowFunction = function(vector){
  return(list(
    mean =mean(vector),
    sd  = sd(vector)
    ))
  }

我希望使用dplyr:summarise将结果写入数据框:

iris %>% 
  dplyr::group_by(Species) %>% 
  dplyr::summarise(
    mean = SlowFunction(Sepal.Length)$mean,
    sd   = SlowFunction(Sepal.Length)$sd
    )

请问有没有办法可以只调用一次 SlowFunction,而不是两次呢?(在我的代码中 SlowFunction 是一个需要多次调用的缓慢函数。)当然,不要将 SlowFunction 拆分成两个部分。所以实际上我希望能够以一种方式在一个语句中填充数据框的多列。


这个有用吗?https://dev59.com/M67la4cB1Zd3GeqPeISV#52413631? - Tung
4个回答

4

如果不改变您当前的SlowFunction,一种方法是使用do

library(dplyr)

iris %>% 
   group_by(Species) %>% 
   do(data.frame(SlowFunction(.$Sepal.Length)))

#  Species     mean    sd
#  <fct>      <dbl> <dbl>
#1 setosa      5.01 0.352
#2 versicolor  5.94 0.516
#3 virginica   6.59 0.636

或者使用 group_split + purrr::map_dfr

bind_cols(Species = unique(iris$Species), iris %>%
     group_split(Species) %>%
     map_dfr(~SlowFunction(.$Sepal.Length)))

3
使用的一个选项是将 SlowFunction 的输出结果存储在 data.frame 的一个 list 列中,然后使用 unnest 进行展开操作。
iris %>%
    group_by(Species) %>%
    summarise(res = list(as.data.frame(SlowFunction(Sepal.Length)))) %>%
    unnest()
## A tibble: 3 x 3
#  Species     mean    sd
#  <fct>      <dbl> <dbl>
#1 setosa      5.01 0.352
#2 versicolor  5.94 0.516
#3 virginica   6.59 0.636

谢谢,我已经比较了答案,这个在我的情况下显然是最快的。它比使用“do”快2倍,比使用group_map快2.5倍! - Frank

3
如果您使用的是dplyr 0.8.0或更高版本,可以使用group_map。需要将SlowFunction的输出转换为数据框架。
library(dplyr)

iris %>% 
  group_by(Species) %>% 
  group_map(~SlowFunction(.x$Sepal.Length) %>% as.data.frame())
# # A tibble: 3 x 3
# # Groups:   Species [3]
#   Species     mean    sd
#   <fct>      <dbl> <dbl>
# 1 setosa      5.01 0.352
# 2 versicolor  5.94 0.516
# 3 virginica   6.59 0.636

3
我们可以将SlowFunction修改为返回一个tibble并且……
SlowFunction = function(vector){
  tibble(
     mean =mean(vector),
      sd  = sd(vector)
     )
   }

然后在 list 中使用 unnest 函数解开 summarise 的输出

iris %>% 
    group_by(Species) %>% 
    summarise(out = list(SlowFunction(Sepal.Length))) %>%
    unnest
# A tibble: 3 x 3
#  Species     mean    sd
#  <fct>      <dbl> <dbl>
#1 setosa      5.01 0.352
#2 versicolor  5.94 0.516
#3 virginica   6.59 0.636

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接