映射函数通过将函数应用于列表或原子向量的每个元素并返回与输入长度相同的对象来转换其输入。
-
map()
始终返回一个列表。有关返回与输入类型相同的对象的版本,请参阅modify()
系列。 -
map_lgl()
、map_int()
、map_dbl()
和map_chr()
返回指定类型的原子向量(或尝试尝试)。对于这些函数,.f
必须返回适当类型的长度为 1 的向量。 -
map_vec()
简化为输出的通用类型。它适用于大多数类型的简单向量,如日期、POSIXct、因子等。 -
walk()
调用.f
的副作用并返回输入.x
。
用法
map(.x, .f, ..., .progress = FALSE)
map_lgl(.x, .f, ..., .progress = FALSE)
map_int(.x, .f, ..., .progress = FALSE)
map_dbl(.x, .f, ..., .progress = FALSE)
map_chr(.x, .f, ..., .progress = FALSE)
map_vec(.x, .f, ..., .ptype = NULL, .progress = FALSE)
walk(.x, .f, ..., .progress = FALSE)
参数
- .x
-
列表或原子向量。
- .f
-
一个函数,通过以下方式之一指定:
-
命名函数,例如
mean
。 -
匿名函数,例如
\(x) x + 1
或function(x) x + 1
。 -
一个公式,例如
~ .x + 1
。您必须使用.x
来引用第一个参数。仅当您需要向后兼容旧版本的 R 时才推荐。 -
字符串、整数或列表,例如
"idx"
、1
或list("idx", 1)
分别是\(x) pluck(x, "idx")
、\(x) pluck(x, 1)
和\(x) pluck(x, "idx", 1)
的简写。如果索引元素为NULL
或不存在,则可以选择提供.default
以设置默认值。
-
- ...
-
传递给映射函数的附加参数。
我们现在通常建议不要使用
...
将附加(常量)参数传递给.f
。相反,使用简写匿名函数:# Instead of x |> map(f, 1, 2, collapse = ",") # do: x |> map(\(x) f(x, 1, 2, collapse = ","))
这使得更容易理解哪些参数属于哪个函数,并且往往会产生更好的错误消息。
- .progress
-
是否显示进度条。使用
TRUE
打开基本进度条,使用字符串为其命名,或参阅progress_bars 了解更多详细信息。 - .ptype
-
如果是
NULL
,默认情况下,输出类型是结果元素的公共类型。否则,提供 "prototype" 给出所需的输出类型。
值
输出长度由输入的长度决定。输出名称由输入名称确定。输出类型由后缀确定:
-
无后缀:列表;
.f()
可以返回任何内容。 -
_lgl()
、_int()
、_dbl()
、_chr()
分别返回逻辑向量、整数向量、双精度向量或字符向量;.f()
必须返回长度为 1 的兼容原子向量。 -
_vec()
返回原子或 S3 向量,与.f
返回的类型相同。.f
可以返回几乎任何类型的向量,只要其长度为 1。 -
walk()
返回输入.x
(不可见)。这使得它很容易在管道中使用。.f()
的返回值被忽略。
.f
引发的任何错误都将包含在类 purrr_error_indexed 的错误中。
例子
# Compute normal distributions from an atomic vector
1:10 |>
map(rnorm, n = 10)
#> [[1]]
#> [1] 1.6215527 2.1484116 -0.8218177 0.7526747 0.7558004 0.7172946
#> [7] 0.4463006 1.6289820 3.0650249 -0.6309894
#>
#> [[2]]
#> [1] 2.5124269 0.1369885 1.4779875 1.9473981 2.5429963 1.0859252 2.4681544
#> [8] 2.3629513 0.6954565 2.7377763
#>
#> [[3]]
#> [1] 4.888505 2.902555 2.064153 2.984050 2.173211 1.487600 3.935363
#> [8] 3.176489 3.243685 4.623549
#>
#> [[4]]
#> [1] 4.112038 3.866003 2.089913 3.720763 3.686554 5.067308 4.070035
#> [8] 3.360877 3.950035 3.748517
#>
#> [[5]]
#> [1] 5.444797 7.755418 5.046531 5.577709 5.118195 3.088280 5.862086
#> [8] 4.756763 4.793913 5.019178
#>
#> [[6]]
#> [1] 6.029561 6.549828 3.725885 8.682557 5.638779 6.213356 7.074346
#> [8] 5.334912 7.113952 5.754104
#>
#> [[7]]
#> [1] 5.822437 6.024149 8.065057 7.131671 7.488629 5.300549 5.529264
#> [8] 7.284150 8.337320 7.236696
#>
#> [[8]]
#> [1] 9.318293 8.523910 8.606748 7.890064 8.172182 7.909673 9.924343
#> [8] 9.298393 8.748791 8.556224
#>
#> [[9]]
#> [1] 8.451743 10.110535 6.387666 8.844306 9.433890 8.618049 9.424188
#> [8] 10.063102 10.048713 8.961897
#>
#> [[10]]
#> [1] 10.486149 11.672883 9.645639 10.946348 11.316826 9.703360 9.612786
#> [8] 9.214567 8.943263 9.204459
#>
# You can also use an anonymous function
1:10 |>
map(\(x) rnorm(10, x))
#> [[1]]
#> [1] -0.7562754 0.3094621 0.4414580 0.4633367 1.2271271 1.9784549
#> [7] 0.7911173 -0.3994105 1.2585373 0.5582005
#>
#> [[2]]
#> [1] 2.5685999 4.1268505 2.4248584 0.3157185 2.2494018 3.0728383 4.0393693
#> [8] 2.4494538 3.3918140 2.4265665
#>
#> [[3]]
#> [1] 3.107584 3.022295 3.603611 2.737349 2.471736 3.192149 1.853800
#> [8] 3.846185 3.081720 1.694883
#>
#> [[4]]
#> [1] 3.055088 4.454342 3.144797 3.713105 4.894962 4.067304 3.837324
#> [8] 3.172690 5.876506 4.766440
#>
#> [[5]]
#> [1] 5.979957 6.321781 3.880289 5.514600 3.490900 6.532741 5.429147
#> [8] 5.122103 3.861988 4.441985
#>
#> [[6]]
#> [1] 7.052539 6.677684 6.038500 5.643619 6.782844 6.804412 4.099939
#> [8] 6.935784 5.690948 6.263067
#>
#> [[7]]
#> [1] 5.209408 6.211741 5.866978 7.363653 6.714112 7.517669 6.897091
#> [8] 6.025930 8.270672 7.960865
#>
#> [[8]]
#> [1] 8.768721 9.035931 7.526113 6.724665 7.694379 10.211769 6.958332
#> [8] 6.853476 6.324673 9.525939
#>
#> [[9]]
#> [1] 9.554186 10.993110 8.845879 11.564408 10.061999 10.142695 10.123839
#> [8] 8.602999 8.176739 8.421115
#>
#> [[10]]
#> [1] 11.763789 10.132992 10.376499 11.138708 11.241263 10.612091 9.570620
#> [8] 11.360461 9.929143 9.727846
#>
# Simplify output to a vector instead of a list by computing the mean of the distributions
1:10 |>
map(rnorm, n = 10) |> # output a list
map_dbl(mean) # output an atomic vector
#> [1] 0.449421 2.083007 2.739160 4.144721 4.716806 5.978606 6.593186
#> [8] 8.619169 9.087989 10.312465
# Using set_names() with character vectors is handy to keep track
# of the original inputs:
set_names(c("foo", "bar")) |> map_chr(paste0, ":suffix")
#> foo bar
#> "foo:suffix" "bar:suffix"
# Working with lists
favorite_desserts <- list(Sophia = "banana bread", Eliott = "pancakes", Karina = "chocolate cake")
favorite_desserts |> map_chr(\(food) paste(food, "rocks!"))
#> Sophia Eliott Karina
#> "banana bread rocks!" "pancakes rocks!" "chocolate cake rocks!"
# Extract by name or position
# .default specifies value for elements that are missing or NULL
l1 <- list(list(a = 1L), list(a = NULL, b = 2L), list(b = 3L))
l1 |> map("a", .default = "???")
#> [[1]]
#> [1] 1
#>
#> [[2]]
#> [1] "???"
#>
#> [[3]]
#> [1] "???"
#>
l1 |> map_int("b", .default = NA)
#> [1] NA 2 3
l1 |> map_int(2, .default = NA)
#> [1] NA 2 NA
# Supply multiple values to index deeply into a list
l2 <- list(
list(num = 1:3, letters[1:3]),
list(num = 101:103, letters[4:6]),
list()
)
l2 |> map(c(2, 2))
#> [[1]]
#> [1] "b"
#>
#> [[2]]
#> [1] "e"
#>
#> [[3]]
#> NULL
#>
# Use a list to build an extractor that mixes numeric indices and names,
# and .default to provide a default value if the element does not exist
l2 |> map(list("num", 3))
#> [[1]]
#> [1] 3
#>
#> [[2]]
#> [1] 103
#>
#> [[3]]
#> NULL
#>
l2 |> map_int(list("num", 3), .default = NA)
#> [1] 3 103 NA
# Working with data frames
# Use map_lgl(), map_dbl(), etc to return a vector instead of a list:
mtcars |> map_dbl(sum)
#> mpg cyl disp hp drat wt qsec vs
#> 642.900 198.000 7383.100 4694.000 115.090 102.952 571.160 14.000
#> am gear carb
#> 13.000 118.000 90.000
# A more realistic example: split a data frame into pieces, fit a
# model to each piece, summarise and extract R^2
mtcars |>
split(mtcars$cyl) |>
map(\(df) lm(mpg ~ wt, data = df)) |>
map(summary) |>
map_dbl("r.squared")
#> 4 6 8
#> 0.5086326 0.4645102 0.4229655
相关用法
- R purrr map_if 有条件地将函数应用于向量的每个元素
- R purrr map2 映射两个输入
- R purrr map_depth 在给定深度映射/修改元素
- R purrr map_dfr 返回数据帧的函数
- R purrr modify_in 修改拔取位置
- R purrr modify_tree 递归修改列表
- R purrr modify 有选择地修改元素
- R purrr accumulate 累积向量缩减的中间结果
- R purrr imap 将函数应用于向量的每个元素及其索引
- R purrr list_transpose 转置列表
- R purrr as_vector 将列表强制转换为向量
- R purrr array-coercion 强制数组列出
- R purrr auto_browse 包装一个函数,以便在出错时自动 browser()
- R purrr pluck 安全地获取或设置嵌套数据结构深处的元素
- R purrr insistently 将函数转换为等待,然后在错误后重试
- R purrr list_simplify 将列表简化为原子或 S3 向量
- R purrr rerun 多次重新运行表达式
- R purrr quietly 包装一个函数来捕获副作用
- R purrr list_flatten 压平列表
- R purrr pmap 同时映射多个输入(“并行”)
- R purrr possibly 包装函数以返回值而不是错误
- R purrr head_while 查找全部满足谓词的头/尾。
- R purrr rbernoulli 从伯努利分布生成随机样本
- R purrr rate-helpers 创建延迟率设置
- R purrr keep_at 根据元素的名称/位置保留/丢弃元素
注:本文由纯净天空筛选整理自Hadley Wickham等大神的英文原创作品 Apply a function to each element of a vector。非经特殊声明,原始代码版权归原作者所有,本译文未经允许或授权,请勿转载或复制。