我有一个返回列表的函数.我正在使用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)
我怎样才能更有效地做到这一点?
使用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.
我们可以用 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)
或者,如果我们可以通过引用(quote或quo)来更改函数,则会变得更加容易
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)