我有一个返回列表的函数。我使用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)
如何更有效地完成这项工作?
答案 0 :(得分:6)
使用purrr
- 包可以解决此问题,例如:
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
请注意,我将函数的输出从列表更改为tibble。
答案 1 :(得分: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
或者如果我们可以通过引用(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
答案 2 :(得分:2)
我可能在这里错过了一些非常明显的东西,但是你似乎两次运行该函数来产生两个答案。为了让事情变得非常简单,请尝试:
library(dplyr)
have <- data.frame(x=seq(1:10),y=1,z=0)
want <- have %>%
dplyr::mutate(x2 = (x * 2 + z),
x3 = (x * 3 + z))
这有帮助吗?或者你的例子简化了你想要实现的目标?
答案 3 :(得分:1)
对mutate使用不同的函数,你应该能够:
library(dplyr)
createMultiX <- function(inputX, inputZ, multiplier) {
inputX * multiplier + inputZ
}
have <- data.frame(x=seq(1:10),y=1,z=0)
want <- have %>%
dplyr::mutate(x2 = createMultiX(x, z, 2),
x3 = createMultiX(x, z, 3))
(事先道歉,因为我在没有访问R终端的情况下盲目地写这个,所以希望它第一次没有错别字!)