利用 purrr::pmap 的 .f 列表名称
Harnessing .f list names with purrr::pmap
以下工作正常:
pmap_dbl(iris, ~ ..1 + ..2 + ..3 + ..4)
.l
的文档提供 A list of lists. ... List names will be used if present.
。这表明您应该能够使用列表名称(即列名称)。然而:
pmap_dbl(iris, ~ Sepal.Length + Sepal.Width + Petal.Length + Petal.Width)
Error in .f(Sepal.Length = .l[[c(1L, i)]], Sepal.Width = .l[[c(2L, i)]], :
object 'Sepal.Length' not found
如何在实践中利用列表名称?
library(purrr)
named_list <- list(one = c(1, 1),
two = c(2, 2),
three = c(3, 3))
pmap(named_list, function(one, two, three) one + two + three)
甚至在 pmap
文档中:
# Matching arguments by name
l <- list(a = x, b = y, c = z)
pmap(l, function(c, b, a) a / (b + c))
之所以可行,是因为它希望清楚地看到每个命名元素。
pmap_dbl(iris, function(Sepal.Length, Sepal.Width, Petal.Length, Petal.Width, Species) Sepal.Length + Sepal.Width)
你也可以利用 ...
似乎:
pmap_dbl(iris, function(Sepal.Length, Sepal.Width, ...) Sepal.Length + Sepal.Width)
理想情况下,此示例在实践中只使用 rowSums
。
公式参数 ~ Sepal.Length + Sepal.Width + Petal.Length + Petal.Width
传递给 purrr::as_mapper
。
purrr::as_mapper(~ Sepal.Length + Sepal.Width + Petal.Length + Petal.Width)
# function (..., .x = ..1, .y = ..2, . = ..1)
# Sepal.Length + Sepal.Width + Petal.Length + Petal.Width
你可以看到这个函数没有直接的方法知道这些变量是什么。
我可以想到 3 种解决方法。我将使用@zacdav 的示例,因为它比您的示例更紧凑、更易读:
named_list <- list(one = c(1, 1),
two = c(2, 2),
three = c(3, 3))
显式定义
您可以明确定义这些变量,如@zacdav 的回答所示。
探索点参数
有一种方法可以通过 as_mapper
返回的函数的 ...
参数访问命名参数。
函数的参数在名称可用时命名,换言之,如文档所述。
这解释了为什么 pmap(named_list, function(x,y,z) x+y+z)
会失败并出现错误:
unused arguments (one = .l[[c(1, i)]], two = .l[[c(2, i)]], three = .l[[c(3, i)]])
参见:
pmap(named_list, ~names(list(...)))
# [[1]]
# [1] "one" "two" "three"
#
# [[2]]
# [1] "one" "two" "three"
(pmap(unname(named_list), function(x,y,z) x+y+z)
另一方面可以正常工作)
所以这会起作用:
pmap(named_list, ~ with(list(...), one + two + three))
# [[1]]
# [1] 6
#
# [[2]]
# [1] 6
使用pryr::f
pryr
为函数定义提供了一个简洁的快捷方式 pryr::f
:
library(pryr)
f(one + two + three)
# function (one, three, two)
# one + two + three
pmap(named_list, f(one + two + three))
# [[1]]
# [1] 6
#
# [[2]]
# [1] 6
#
但是在使用它时要小心,全局变量仍将显示为参数,函数是否包含在参数中取决于它们的调用方式。例如:
x <- 1
test <- mean
f(test(x) + lapply(iris,test2))
# function (iris, test2, x)
# test(x) + lapply(iris, test2)
所以这不是一个通用的方法,您应该只在简单的情况下使用它。第二种方法,虽然有点 hack,但将是通用的。
此外 f
是按字母顺序排列参数,这在处理命名列表时应该不是问题,但在处理部分命名列表时要小心。
以下工作正常:
pmap_dbl(iris, ~ ..1 + ..2 + ..3 + ..4)
.l
的文档提供 A list of lists. ... List names will be used if present.
。这表明您应该能够使用列表名称(即列名称)。然而:
pmap_dbl(iris, ~ Sepal.Length + Sepal.Width + Petal.Length + Petal.Width)
Error in .f(Sepal.Length = .l[[c(1L, i)]], Sepal.Width = .l[[c(2L, i)]], :
object 'Sepal.Length' not found
如何在实践中利用列表名称?
library(purrr)
named_list <- list(one = c(1, 1),
two = c(2, 2),
three = c(3, 3))
pmap(named_list, function(one, two, three) one + two + three)
甚至在 pmap
文档中:
# Matching arguments by name
l <- list(a = x, b = y, c = z)
pmap(l, function(c, b, a) a / (b + c))
之所以可行,是因为它希望清楚地看到每个命名元素。
pmap_dbl(iris, function(Sepal.Length, Sepal.Width, Petal.Length, Petal.Width, Species) Sepal.Length + Sepal.Width)
你也可以利用 ...
似乎:
pmap_dbl(iris, function(Sepal.Length, Sepal.Width, ...) Sepal.Length + Sepal.Width)
理想情况下,此示例在实践中只使用 rowSums
。
公式参数 ~ Sepal.Length + Sepal.Width + Petal.Length + Petal.Width
传递给 purrr::as_mapper
。
purrr::as_mapper(~ Sepal.Length + Sepal.Width + Petal.Length + Petal.Width)
# function (..., .x = ..1, .y = ..2, . = ..1)
# Sepal.Length + Sepal.Width + Petal.Length + Petal.Width
你可以看到这个函数没有直接的方法知道这些变量是什么。
我可以想到 3 种解决方法。我将使用@zacdav 的示例,因为它比您的示例更紧凑、更易读:
named_list <- list(one = c(1, 1),
two = c(2, 2),
three = c(3, 3))
显式定义
您可以明确定义这些变量,如@zacdav 的回答所示。
探索点参数
有一种方法可以通过 as_mapper
返回的函数的 ...
参数访问命名参数。
函数的参数在名称可用时命名,换言之,如文档所述。
这解释了为什么 pmap(named_list, function(x,y,z) x+y+z)
会失败并出现错误:
unused arguments (one = .l[[c(1, i)]], two = .l[[c(2, i)]], three = .l[[c(3, i)]])
参见:
pmap(named_list, ~names(list(...)))
# [[1]]
# [1] "one" "two" "three"
#
# [[2]]
# [1] "one" "two" "three"
(pmap(unname(named_list), function(x,y,z) x+y+z)
另一方面可以正常工作)
所以这会起作用:
pmap(named_list, ~ with(list(...), one + two + three))
# [[1]]
# [1] 6
#
# [[2]]
# [1] 6
使用pryr::f
pryr
为函数定义提供了一个简洁的快捷方式 pryr::f
:
library(pryr)
f(one + two + three)
# function (one, three, two)
# one + two + three
pmap(named_list, f(one + two + three))
# [[1]]
# [1] 6
#
# [[2]]
# [1] 6
#
但是在使用它时要小心,全局变量仍将显示为参数,函数是否包含在参数中取决于它们的调用方式。例如:
x <- 1
test <- mean
f(test(x) + lapply(iris,test2))
# function (iris, test2, x)
# test(x) + lapply(iris, test2)
所以这不是一个通用的方法,您应该只在简单的情况下使用它。第二种方法,虽然有点 hack,但将是通用的。
此外 f
是按字母顺序排列参数,这在处理命名列表时应该不是问题,但在处理部分命名列表时要小心。