apply/map 数据框中每行具有不同参数的不同函数
apply/map a different function per row in a data frame with varying parameters
我有一个简单的问题要问你们 purrr-experts 有一段时间我最好的 google 努力都没有解决。首先,让我们看一下我尝试使用的嵌套列表数据结构。
加载包
#R version 3.4.1
library(purrr) # version 0.2.4
library(dplyr) # version 0.7.4
定义函数
f1 <- function(a, b, c) {a + b^c}
f2 <- function(x) {x * 2}
f3 <- function(y, z) {y * z}
定义参数集
这些将传递给 f1
、f2
和 f3
中的每一个:
p1 <- data_frame(a = c(2, 4, 5, 7, 8),
b = c(1, 1, 2, 2, 2),
c = c(.5, 5, 1, 2, 3))
p2 <- data_frame(x = c(1, 4))
p3 <- data_frame(y = c(2, 2, 2, 3),
z = c(5, 4, 3, 2))
将它们放在一个嵌套的数据框中
我试图让我的数据在一个漂亮、整洁的矩形中易于使用。 "id" 变量是函数名称本身(在我的真实数据中,有数百个):
df <- data_frame(fun_id = c('f1', 'f2', 'f3'),
params = list(p1, p2, p3),
funs = list(f1, f2, f3))
检查结构向我们显示 params
和 funs
:
的列表列
print(df)
# A tibble: 3 x 3
fun_id params funs
<chr> <list> <list>
1 f1 <tibble [5 x 3]> <fun>
2 f2 <tibble [2 x 1]> <fun>
3 f3 <tibble [4 x 2]> <fun>
我的问题
使用 purrr
函数,也许 dplyr::mutate
,如何在 df
中获得一个名为 results
的新列表列,其中每个元素都是一个列表,其中包含使用取自 params
的参数以行方式执行 funs
中的函数的输出?
我可以让 pmap
为一个简单的案例做我想做的事:
> pmap(.l = p1, .f = f1)
[[1]]
[1] 3
[[2]]
[1] 5
[[3]]
[1] 7
[[4]]
[1] 11
[[5]]
[1] 16
但我真的想在数据框中执行此操作以保持一切正常。以下内容使我找到了正确的结构(一个带有结果列表列的数据框),但仅针对一行并且没有概括:
> df %>%
slice(1) %>%
mutate(results = list(pmap(.l = params[[1]], .f = funs[[1]])))
# A tibble: 1 x 4
fun_id params funs results
<chr> <list> <list> <list>
1 f1 <tibble [5 x 3]> <fun> <list [5]>
提前感谢您帮助解决我的问题!
P.S。我查看了以下资源,但尚未找到答案:
http://statwonk.com/purrr.html
我们可以使用 map2
并为每一行应用 pmap
函数。
df2 <- df %>%
mutate(result = map2(params, funs, ~pmap(.l = .x, .f = .y)))
df2
# # A tibble: 3 x 4
# fun_id params funs result
# <chr> <list> <list> <list>
# 1 f1 <tibble [5 x 3]> <fn> <list [5]>
# 2 f2 <tibble [2 x 1]> <fn> <list [2]>
# 3 f3 <tibble [4 x 2]> <fn> <list [4]>
purrr
中有一个方便的功能正是针对这种情况;将函数列表应用于相应的参数列表!它被称为 invoke_map
并且可以与 mutate
一起使用,如下所示。我认为与 map2(~pmap())
相比的主要优势在于,如果有额外的参数提供给 params
中未包含的任何函数,您可以将它们作为命名参数添加到 ...
中,而不需要修改 params
.
library(tidyverse)
f1 <- function(a, b, c) {a + b^c}
f2 <- function(x) {x * 2}
f3 <- function(y, z) {y * z}
p1 <- data_frame(
a = c(2, 4, 5, 7, 8),
b = c(1, 1, 2, 2, 2),
c = c(.5, 5, 1, 2, 3)
)
p2 <- data_frame(x = c(1, 4))
p3 <- data_frame(
y = c(2, 2, 2, 3),
z = c(5, 4, 3, 2)
)
df <- data_frame(
fun_id = c("f1", "f2", "f3"),
params = list(p1, p2, p3),
funs = list(f1, f2, f3)
)
df2 <- df %>%
mutate(results = invoke_map(.f = funs, .x = params))
df2
#> # A tibble: 3 x 4
#> fun_id params funs results
#> <chr> <list> <list> <list>
#> 1 f1 <tibble [5 x 3]> <fn> <dbl [5]>
#> 2 f2 <tibble [2 x 1]> <fn> <dbl [2]>
#> 3 f3 <tibble [4 x 2]> <fn> <dbl [4]>
df2$results
#> [[1]]
#> [1] 3 5 7 11 16
#>
#> [[2]]
#> [1] 2 8
#>
#> [[3]]
#> [1] 10 8 6 6
由 reprex package (v0.2.0) 创建于 2018-07-13。
我有一个简单的问题要问你们 purrr-experts 有一段时间我最好的 google 努力都没有解决。首先,让我们看一下我尝试使用的嵌套列表数据结构。
加载包
#R version 3.4.1
library(purrr) # version 0.2.4
library(dplyr) # version 0.7.4
定义函数
f1 <- function(a, b, c) {a + b^c}
f2 <- function(x) {x * 2}
f3 <- function(y, z) {y * z}
定义参数集
这些将传递给 f1
、f2
和 f3
中的每一个:
p1 <- data_frame(a = c(2, 4, 5, 7, 8),
b = c(1, 1, 2, 2, 2),
c = c(.5, 5, 1, 2, 3))
p2 <- data_frame(x = c(1, 4))
p3 <- data_frame(y = c(2, 2, 2, 3),
z = c(5, 4, 3, 2))
将它们放在一个嵌套的数据框中
我试图让我的数据在一个漂亮、整洁的矩形中易于使用。 "id" 变量是函数名称本身(在我的真实数据中,有数百个):
df <- data_frame(fun_id = c('f1', 'f2', 'f3'),
params = list(p1, p2, p3),
funs = list(f1, f2, f3))
检查结构向我们显示 params
和 funs
:
print(df)
# A tibble: 3 x 3
fun_id params funs
<chr> <list> <list>
1 f1 <tibble [5 x 3]> <fun>
2 f2 <tibble [2 x 1]> <fun>
3 f3 <tibble [4 x 2]> <fun>
我的问题
使用 purrr
函数,也许 dplyr::mutate
,如何在 df
中获得一个名为 results
的新列表列,其中每个元素都是一个列表,其中包含使用取自 params
的参数以行方式执行 funs
中的函数的输出?
我可以让 pmap
为一个简单的案例做我想做的事:
> pmap(.l = p1, .f = f1)
[[1]]
[1] 3
[[2]]
[1] 5
[[3]]
[1] 7
[[4]]
[1] 11
[[5]]
[1] 16
但我真的想在数据框中执行此操作以保持一切正常。以下内容使我找到了正确的结构(一个带有结果列表列的数据框),但仅针对一行并且没有概括:
> df %>%
slice(1) %>%
mutate(results = list(pmap(.l = params[[1]], .f = funs[[1]])))
# A tibble: 1 x 4
fun_id params funs results
<chr> <list> <list> <list>
1 f1 <tibble [5 x 3]> <fun> <list [5]>
提前感谢您帮助解决我的问题!
P.S。我查看了以下资源,但尚未找到答案:
http://statwonk.com/purrr.html
我们可以使用 map2
并为每一行应用 pmap
函数。
df2 <- df %>%
mutate(result = map2(params, funs, ~pmap(.l = .x, .f = .y)))
df2
# # A tibble: 3 x 4
# fun_id params funs result
# <chr> <list> <list> <list>
# 1 f1 <tibble [5 x 3]> <fn> <list [5]>
# 2 f2 <tibble [2 x 1]> <fn> <list [2]>
# 3 f3 <tibble [4 x 2]> <fn> <list [4]>
purrr
中有一个方便的功能正是针对这种情况;将函数列表应用于相应的参数列表!它被称为 invoke_map
并且可以与 mutate
一起使用,如下所示。我认为与 map2(~pmap())
相比的主要优势在于,如果有额外的参数提供给 params
中未包含的任何函数,您可以将它们作为命名参数添加到 ...
中,而不需要修改 params
.
library(tidyverse)
f1 <- function(a, b, c) {a + b^c}
f2 <- function(x) {x * 2}
f3 <- function(y, z) {y * z}
p1 <- data_frame(
a = c(2, 4, 5, 7, 8),
b = c(1, 1, 2, 2, 2),
c = c(.5, 5, 1, 2, 3)
)
p2 <- data_frame(x = c(1, 4))
p3 <- data_frame(
y = c(2, 2, 2, 3),
z = c(5, 4, 3, 2)
)
df <- data_frame(
fun_id = c("f1", "f2", "f3"),
params = list(p1, p2, p3),
funs = list(f1, f2, f3)
)
df2 <- df %>%
mutate(results = invoke_map(.f = funs, .x = params))
df2
#> # A tibble: 3 x 4
#> fun_id params funs results
#> <chr> <list> <list> <list>
#> 1 f1 <tibble [5 x 3]> <fn> <dbl [5]>
#> 2 f2 <tibble [2 x 1]> <fn> <dbl [2]>
#> 3 f3 <tibble [4 x 2]> <fn> <dbl [4]>
df2$results
#> [[1]]
#> [1] 3 5 7 11 16
#>
#> [[2]]
#> [1] 2 8
#>
#> [[3]]
#> [1] 10 8 6 6
由 reprex package (v0.2.0) 创建于 2018-07-13。