使用列名围绕 purrr::pmap 包装函数
Wrapping function around purrr::pmap using column names
我尝试编写一个围绕 purrr::pmap_dbl() 函数的简单函数。
我有以下数据:
df <- data.frame(
col1 = 1:5,
col2 = 2:6,
col3 = 3:7
)
以及以下函数:
addfn <- function(x, y){
x^2 + y
}
然后我想写一个像这样的函数:
testfn <- function(data, a, b){
purrr::pmap_dbl(data, function(a, b, ...) addfn(a, b))
}
不幸的是,testfn(df, col1, col2)
在这种情况下给出了一个错误。我想获得与通过以下方式获得的输出相同的输出:
purrr::pmap_dbl(df, function(col1, col2, ...) addfn(col1, col2))
有什么方法可以做到这一点?
您可以 select 进入您的 df,然后再在地图中使用它:
library(rlang)
library(dplyr)
library(purrr)
testfn <- function(data, x, y){
data <- select(data, !!enquo(x), !!enquo(y))
pmap_dbl(data, ~ addfn(.x, .y))
}
testfn(df, col1, col3)
或者您可以使用 apply
函数。
addfn <- function(x){
apply(x,1,function(y) y[1]^2 + y[2])
}
addfn(df[,1:2])
[1] 3 7 13 21 31
addfn(df[,2:3])
[1] 7 13 21 31 43
1) testfn 首先,请注意使用 testfn
从这个已经有效的问题:
testfn(unname(df[c("col1", "col3")]))
## [1] 4 8 14 22 32
2) testfn2 我们可以修改为:
testfn2 <- function(data, ...) {
data %>% select(...) %>% unname %>% purrr::pmap_dbl(addfn)
}
testfn2(df, col1, col3)
## [1] 4 8 14 22 32
testfn2(df, "col1", "col3")
## [1] 4 8 14 22 32
3) base R 当然,正如已经指出的那样,我们并不真的需要 purrr。这在 base R 中有效,因为 addfn
是矢量化的:
with(df, addfn(col1, col3))
## [1] 4 8 14 22 32
或者如果 addfn
没有向量化那么:
with(df, mapply(addfn, col1, col3))
## [1] 4 8 14 22 32
我们可以使用标准计算来编写此函数:
testfn3 <- function(data, a, b) mapply(addfn, df[[a]], df[[b]])
testfn3(df, "col1", "col3")
## [1] 4 8 14 22 32
或使用非标准评估:
testfn4 <- function(data, ...) eval.parent(substitute(
with(data, mapply(addfn, ...))
))
testfn4(df, col1, col3)
## [1] 4 8 14 22 32
我尝试编写一个围绕 purrr::pmap_dbl() 函数的简单函数。
我有以下数据:
df <- data.frame(
col1 = 1:5,
col2 = 2:6,
col3 = 3:7
)
以及以下函数:
addfn <- function(x, y){
x^2 + y
}
然后我想写一个像这样的函数:
testfn <- function(data, a, b){
purrr::pmap_dbl(data, function(a, b, ...) addfn(a, b))
}
不幸的是,testfn(df, col1, col2)
在这种情况下给出了一个错误。我想获得与通过以下方式获得的输出相同的输出:
purrr::pmap_dbl(df, function(col1, col2, ...) addfn(col1, col2))
有什么方法可以做到这一点?
您可以 select 进入您的 df,然后再在地图中使用它:
library(rlang)
library(dplyr)
library(purrr)
testfn <- function(data, x, y){
data <- select(data, !!enquo(x), !!enquo(y))
pmap_dbl(data, ~ addfn(.x, .y))
}
testfn(df, col1, col3)
或者您可以使用 apply
函数。
addfn <- function(x){
apply(x,1,function(y) y[1]^2 + y[2])
}
addfn(df[,1:2])
[1] 3 7 13 21 31
addfn(df[,2:3])
[1] 7 13 21 31 43
1) testfn 首先,请注意使用 testfn
从这个已经有效的问题:
testfn(unname(df[c("col1", "col3")]))
## [1] 4 8 14 22 32
2) testfn2 我们可以修改为:
testfn2 <- function(data, ...) {
data %>% select(...) %>% unname %>% purrr::pmap_dbl(addfn)
}
testfn2(df, col1, col3)
## [1] 4 8 14 22 32
testfn2(df, "col1", "col3")
## [1] 4 8 14 22 32
3) base R 当然,正如已经指出的那样,我们并不真的需要 purrr。这在 base R 中有效,因为 addfn
是矢量化的:
with(df, addfn(col1, col3))
## [1] 4 8 14 22 32
或者如果 addfn
没有向量化那么:
with(df, mapply(addfn, col1, col3))
## [1] 4 8 14 22 32
我们可以使用标准计算来编写此函数:
testfn3 <- function(data, a, b) mapply(addfn, df[[a]], df[[b]])
testfn3(df, "col1", "col3")
## [1] 4 8 14 22 32
或使用非标准评估:
testfn4 <- function(data, ...) eval.parent(substitute(
with(data, mapply(addfn, ...))
))
testfn4(df, col1, col3)
## [1] 4 8 14 22 32