當前位置: 首頁>>代碼示例 >>用法及示例精選 >>正文


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。非經特殊聲明,原始代碼版權歸原作者所有,本譯文未經允許或授權,請勿轉載或複製。