以下工作正常:
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
在实践中如何利用列表名称?
答案 0 :(得分:5)
公式参数~ 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
参数访问命名参数。
当名称可用时,将命名函数的参数,如doc所指出的那样。
这说明了pmap(named_list, function(x,y,z) x+y+z)
会因错误而失败的原因:
未使用的参数(一个= .l [[c(1,i)]],两个= .l [[c(2,i)]],三个= .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)
因此,这不是通用方法,您应该仅在简单情况下使用它。第二种方法虽然有点破绽,但却很普遍。
此外,f
按字母顺序对参数进行排序,在处理命名列表时这不是问题,但是在处理部分命名列表时要小心。
答案 1 :(得分:3)
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
。