R dplyr :: mutate - 在返回的列表中添加所有元素

Dom*_*azz 4 r dplyr

我有一个返回列表的函数.我正在使用mutate在与输出对应的数据框中添加列.计算相当复杂,所以我宁愿只调用一次函数.我对R和dplry很新,并且无法找到一种更有效的方法.

这是我现在正在做的一个非常简单的例子.

library(dplyr)

testFun <- function(x,z)
{
  list(x2=x*x + z, x3=x*x*x + z)
}

have <- data.frame(x=seq(1:10),y=1,z=0)

want <- have %>%
        dplyr::mutate(x2=testFun(x,z)$x2,
                      x3=testFun(x,z)$x3)
Run Code Online (Sandbox Code Playgroud)

我怎样才能更有效地做到这一点?

kat*_*ath 6

使用purrr-package可以解决这个问题,例如:

library(purrr)
library(dplyr)

testFun <- function(x,z) {
  tibble(x2=x*x + z, x3=x*x*x + z)
}

have %>%
  mutate(new_x = map2(x, z, testFun)) %>% 
  unnest(new_x)

#     x y z  x2   x3
# 1   1 1 0   1    1
# 2   2 1 0   4    8
# 3   3 1 0   9   27
# 4   4 1 0  16   64
# 5   5 1 0  25  125
# 6   6 1 0  36  216
# 7   7 1 0  49  343
# 8   8 1 0  64  512
# 9   9 1 0  81  729
# 10 10 1 0 100 1000
Run Code Online (Sandbox Code Playgroud)

请注意,我将函数的输出从列表更改为tibble.


akr*_*run 5

我们可以用 pmap

library(purrr)
library(dplyr)
pmap_dfr(have %>% 
              select(x, z), testFun) %>%
   bind_cols(have, .)
#    x y z  x2   x3
#1   1 1 0   1    1
#2   2 1 0   4    8
#3   3 1 0   9   27
#4   4 1 0  16   64
#5   5 1 0  25  125
#6   6 1 0  36  216
#7   7 1 0  49  343
#8   8 1 0  64  512
#9   9 1 0  81  729
#10 10 1 0 100 1000
Run Code Online (Sandbox Code Playgroud)

或者,如果我们可以通过引用(quotequo)来更改函数,则会变得更加容易

testFun <- function(x,z){
  list(x2= quo(x*x + z), x3= quo(x*x*x + z))
 }

have %>% 
   mutate(!!! testFun(x, z))
#    x y z  x2   x3
#1   1 1 0   1    1
#2   2 1 0   4    8
#3   3 1 0   9   27
#4   4 1 0  16   64
#5   5 1 0  25  125
#6   6 1 0  36  216
#7   7 1 0  49  343
#8   8 1 0  64  512
#9   9 1 0  81  729
#10 10 1 0 100 1000
Run Code Online (Sandbox Code Playgroud)