当前位置: 首页>>代码示例 >>用法及示例精选 >>正文


R purrr map 将函数应用于向量的每个元素


映射函数通过将函数应用于列表或原子向量的每个元素并返回与输入长度相同的对象来转换其输入。

  • 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 + 1function(x) x + 1

  • 一个公式,例如~ .x + 1 。您必须使用.x 来引用第一个参数。仅当您需要向后兼容旧版本的 R 时才推荐。

  • 字符串、整数或列表,例如"idx"1list("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 的错误中。

也可以看看

map_if() 用于仅将函数应用于 .x 中满足指定条件的元素。

其他Map变体: imap()lmap()map2()map_depth()map_if()modify()pmap()

例子

# 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/map.R

相关用法


注:本文由纯净天空筛选整理自Hadley Wickham等大神的英文原创作品 Apply a function to each element of a vector。非经特殊声明,原始代码版权归原作者所有,本译文未经允许或授权,请勿转载或复制。