- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我有什么理由应该使用
map(<list-like-object>, function(x) <do stuff>)
而不是
lapply(<list-like-object>, function(x) <do stuff>)
输出应该是相同的,我所做的基准测试似乎表明 lapply
稍微快一些(应该是 map
需要评估所有非标准评估输入)。
那么,对于如此简单的情况,我是否应该考虑切换到purrr::map
? ?我在这里并不是询问一个人对 purrr 等提供的语法、其他功能的喜欢或不喜欢,而是严格询问 purrr::map
的比较。与 lapply
假设使用标准评估,即 map(<list-like-object>, function(x) <do stuff>)
。 purrr::map
有什么好处吗?在性能、异常处理等方面有什么?下面的评论表明事实并非如此,但也许有人可以详细说明一下?
最佳答案
如果您在 purrr 中使用的唯一函数是 map()
,那么不,优势并不明显。正如 Rich Pauloo 指出的那样,主要优势map()
是允许您编写紧凑的帮助程序常见特殊情况的代码:
~ . + 1
相当于 function(x) x + 1
(以及 R-4.1 及更高版本中的 \(x) x + 1
)
list("x", 1)
相当于 function(x) x[["x"]][[1]]
。这些助手比 [[
更通用一些- 请参阅?pluck
了解详情。对于 datarectangling , 这 .default
论证特别有帮助。
但大多数时候您不使用单个 *apply()
/map()
函数,你使用了一堆它们,而 purrr 的优点是功能之间具有更大的一致性。例如:
lapply()
的第一个参数是数据;第一个参数 mapply()
是函数。所有映射函数的第一个参数始终是数据。
与 vapply()
, sapply()
,和mapply()
你可以选择使用 USE.NAMES = FALSE
抑制输出中的名称;但 lapply()
没有这个论据。
没有一致的方法将一致的参数传递给映射器功能。大多数函数使用 ...
但是mapply()
用途 MoreArgs
(您希望将其称为 MORE.ARGS
),并且 Map()
, Filter()
和Reduce()
期待你创造一个新的匿名函数。在映射函数中,常量参数总是出现在函数名称之后。
几乎每个 purrr 函数都是类型稳定的:您可以预测输出类型仅来自函数名称。这不适用于 sapply()
或mapply()
。是的,有vapply()
;但没有相当于 mapply()
.
您可能认为所有这些细微差别都不重要(正如有些人认为 stringr 没有任何优势基本 R 正则表达式),但根据我的经验,它们会导致不必要的编程时的摩擦(总是使用不同的参数顺序绊倒我),并且它们使函数式编程技术更难实现学习,因为除了伟大的想法之外,你还必须学习很多东西附带细节。
Purrr 还填充了一些基本 R 中没有的方便的 map 变体:
modify()
使用 [[<-
保留数据类型修改“在与 _if
变体结合使用,这允许(IMO漂亮)代码如 modify_if(df, is.factor, as.character)
map2()
允许您同时映射 x
和y
。这可以更轻松地表达想法,例如 map2(models, datasets, predict)
imap()
允许您同时映射 x
及其指数(姓名或职位)。这使得加载所有内容变得容易(例如) csv
目录中的文件,添加 filename
每个列。
dir("\\.csv$") %>%
set_names() %>%
map(read.csv) %>%
imap(~ transform(.x, filename = .y))
walk()
不可见地返回其输入;当你调用函数的副作用(即将文件写入磁盘)。
更不用说像 safely()
这样的其他助手了和partial()
.
就我个人而言,我发现当我使用purrr时,我可以编写函数式代码摩擦更小,更轻松;它减少了之间的差距提出一个想法并实现它。但您的里程可能会有所不同;没有必要使用 purrr ,除非它确实对您有帮助。
是的,map()
比 lapply()
稍慢。但使用成本 map()
或lapply()
由您所映射的内容驱动,而不是开销执行循环。下面的微基准表明成本的map()
与lapply()
相比每个元素大约 40 ns,其中似乎不太可能对大多数 R 代码产生重大影响。
library(purrr)
n <- 1e4
x <- 1:n
f <- function(x) NULL
mb <- microbenchmark::microbenchmark(
lapply = lapply(x, f),
map = map(x, f)
)
summary(mb, unit = "ns")$median / n
#> [1] 490.343 546.880
关于r - 为什么使用 purrr::map 而不是 lapply?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45101045/
背景 我有一个问题,可能有多种解决方案,但我相信有一个尚未发现的优雅解决方案利用 purrr。 示例代码 我有一个如下的大数据框,为此我在下面提供了一个示例: library(tibble) libr
我正在尝试使用 purrr 的 modify_in 来修改列表的元素。列表示例: tib_list [[1]] #> # A tibble: 5 x 3 #> col_one col_two c
我正在努力了解 purrr,但我正在为一些本应很容易的事情而苦苦挣扎。 假设我有以下男性和女性数据 n 0, "M", "F")), value = rnorm(n) ) 现在,我要计算值列的以下
我想对“ID”以外的所有列应用 Blom 转换。由于它们都是数字,map_if 和 is.numeric 在这里不起作用。 library(rcompanion) data("mtcars") # G
考虑以下数据框列表: library(tidyverse) df1 % set_names(paste0("df", 1:4)) 如果不是这样,我想将 A 和 B 的元素连接到 B 列中。请注意,
我正在尝试使用 purrr对具有相同索引的列表元素求和。这可以使用以下方法在基础 R 中实现: xx % reduce(sum)返回单个值。有谁知道在 purrr 中执行此操作的语法吗? ? 编辑-我
我有类似于df3的数据。要重现数据,请运行以下命令: vec1 % group_by(A) %>% nest() df2 % left_join(df2, by = "A") 我需要使用这样的
我搜索了 ??"~"但这只能指向 rlang::env_bind (大概是 %<~% )和 base::~ .在 RStudio 中,如何找到 Purrr 的 ~的文档?例如,如果我忘记了如何使用 ~
这个问题在这里已经有了答案: Repeat each row of data.frame the number of times specified in a column (9 个回答) 10 个月
我有以下数据框列表,其中包含名为 cyl 的列 # Create 3 dataframes with identical column names mt_list [[1]] #>
我正在查看使用map的example。这里是: mtcars %>% split(.$cyl) %>% # from base R map(~ lm(mpg ~ wt, data = .))
我没有看到任何关于我的问题。我想,当我看到 purrr 很多模型示例时,如何再次使用在数据上创建的模型?一点点代码会告诉你我在追求什么: 这是基本的gapminder许多模型示例。 library(g
这是一个嵌套数据。 df1 % group_by(group) %>% nest() 我需要使用 purrr:map 运行 lm。 map(df2$data, ~lm(A~B, data=.x)) 找
我有一个命名列表,在该列表中我想根据列表的来源名称重命名它们的列。 我的方法的问题似乎是 .x 占位符,我认为它是我唯一的列表名称。但在 rename_with 函数中,.x 似乎是在每个列表数据框中
给定一个 dataframe,比如 iris 默认值,如何配置 purrr::map_dfr() 函数在 的每一行上运行code>dataframe 并执行函数 foo。 这是我的 df 的一行,请注
感谢这个网站,我使用 R purrr 包来聚合基于多列的数据。聚合按我想要的方式工作,但输出却不然。以下是使用 mtcars 数据集的示例。 library(dplyr) library(purrr)
这是一个嵌套数据。 df1 % group_by(group) %>% nest() 我需要使用 purrr:map 运行 lm。 map(df2$data, ~lm(A~B, data=.x)) 找
我有一个命名列表,在该列表中我想根据列表的来源名称重命名它们的列。 我的方法的问题似乎是 .x 占位符,我认为它是我唯一的列表名称。但在 rename_with 函数中,.x 似乎是在每个列表数据框中
给定一个 dataframe,比如 iris 默认值,如何配置 purrr::map_dfr() 函数在 的每一行上运行code>dataframe 并执行函数 foo。 这是我的 df 的一行,请注
也许我遗漏了一些明显的东西,但我试图将 R 中命名列表的命名列表(甚至可能更多嵌套)扁平化为最终一个扁平列表。 purrr和 rlist似乎有工具。我怎样才能实现子列表的名称成为扁平结果列表的名称预加
我是一名优秀的程序员,十分优秀!