r - 使用 purrr::pmap 来利用 .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
在实践中如何利用列表名称?
解决方案
公式参数~ 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's answer中所示,它将起作用。
探索点论点
有一种方法可以通过...
返回的函数的参数访问命名参数as_mapper
。
当名称可用时,函数的参数会被命名,正如文档所说的那样。
这就解释了为什么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
,按字母顺序对参数进行排序,这在处理命名列表时应该不是问题,但在处理部分命名列表时要小心。
推荐阅读
- django-rest-framework - DRF 自定义权限:允许“检索”,拒绝“列表”
- python - InvalidArchiveError 仅在 gxx_linux-64 上
- sql - GORM 嵌入式结构未迁移到 SQL
- php - 从 Laravel 将视频上传到 Youtube,其中视频未本地存储
- angular - 角度弹出窗口不弹出
- javascript - 加载资源失败:当我托管我的页面时,服务器响应状态为 404(未找到)消息?
- powershell - PowerShell 脚本中的 [ ] 问题
- javascript - Web 组件只渲染一次
- flutter - flutter keytool :术语“keytool”未被识别为 cmdlet 的名称
- python - 基于两列比较两个数据帧并打印匹配值并对匹配值进行分组