R语言purrr包详细介绍

KJY / 2022-05-17


R语言purrr包详细介绍

参考:

https://jiaxiangli.netlify.app/2018/02/27/purrr/ https://cloud.tencent.com/developer/article/1771939

urrr包除了占据tidyverse风格核心函数式编程的map_* 功能,还提供非常强大的list操作功能

R写循环有三个境界:

手动for循环 apply循环 purrr泛函式编程

泛函式定义: 函数的函数成为泛函式,map(x,f)中,map是函数,f也是函数,f是map的参数,那么map就是泛函数。 在数学上,函数的函数称为泛函,在编程中表示函数作用在函数上,或者说函数包含其它函数作为参数,这就是泛函式。 循环迭代,本质上就是将一个函数依次应用(映射)到序列的每一个元素上。 表示出来就是泛函式:map_*(x, f)

library(tidyverse)
## ── Attaching packages ─────────────────────────────────────── tidyverse 1.3.1 ──
## ✓ ggplot2 3.3.3     ✓ purrr   0.3.4
## ✓ tibble  3.1.1     ✓ dplyr   1.0.5
## ✓ tidyr   1.1.3     ✓ stringr 1.4.0
## ✓ readr   1.4.0     ✓ forcats 0.5.1
## ── Conflicts ────────────────────────────────────────── tidyverse_conflicts() ──
## x dplyr::filter() masks stats::filter()
## x dplyr::lag()    masks stats::lag()

载入R包tidyverse后,自动加载了8个R包,即ggplot2,tibble,tidyr,readr,purrr,dplyr,stringr,以及forcats(将在下文介绍其中最重要的几个包)。结果还显示,R包dplyr中的filter()函数与lag()函数分别“掩盖”(mask)了同名的R基础函数。如果你想调用R基础函数filter()或lag(),则须使用它们的全称stats::filter()或stats::lag(),从R的基础包stats调用这两个函数。

我们可以通过下面两种方式看一个包内所有的function

ls("package:purrr")
##   [1] "%@%"                 "%>%"                 "%||%"               
##   [4] "accumulate"          "accumulate_right"    "accumulate2"        
##   [7] "array_branch"        "array_tree"          "as_function"        
##  [10] "as_mapper"           "as_vector"           "assign_in"          
##  [13] "at_depth"            "attr_getter"         "auto_browse"        
##  [16] "chuck"               "compact"             "compose"            
##  [19] "cross"               "cross_d"             "cross_df"           
##  [22] "cross_n"             "cross2"              "cross3"             
##  [25] "detect"              "detect_index"        "discard"            
##  [28] "done"                "every"               "exec"               
##  [31] "flatten"             "flatten_chr"         "flatten_dbl"        
##  [34] "flatten_df"          "flatten_dfc"         "flatten_dfr"        
##  [37] "flatten_int"         "flatten_lgl"         "flatten_raw"        
##  [40] "has_element"         "head_while"          "imap"               
##  [43] "imap_chr"            "imap_dbl"            "imap_dfc"           
##  [46] "imap_dfr"            "imap_int"            "imap_lgl"           
##  [49] "imap_raw"            "imodify"             "insistently"        
##  [52] "invoke"              "invoke_map"          "invoke_map_chr"     
##  [55] "invoke_map_dbl"      "invoke_map_df"       "invoke_map_dfc"     
##  [58] "invoke_map_dfr"      "invoke_map_int"      "invoke_map_lgl"     
##  [61] "invoke_map_raw"      "is_atomic"           "is_bare_atomic"     
##  [64] "is_bare_character"   "is_bare_double"      "is_bare_integer"    
##  [67] "is_bare_list"        "is_bare_logical"     "is_bare_numeric"    
##  [70] "is_bare_vector"      "is_character"        "is_double"          
##  [73] "is_empty"            "is_formula"          "is_function"        
##  [76] "is_integer"          "is_list"             "is_logical"         
##  [79] "is_null"             "is_numeric"          "is_rate"            
##  [82] "is_scalar_atomic"    "is_scalar_character" "is_scalar_double"   
##  [85] "is_scalar_integer"   "is_scalar_list"      "is_scalar_logical"  
##  [88] "is_scalar_numeric"   "is_scalar_vector"    "is_vector"          
##  [91] "iwalk"               "keep"                "lift"               
##  [94] "lift_dl"             "lift_dv"             "lift_ld"            
##  [97] "lift_lv"             "lift_vd"             "lift_vl"            
## [100] "list_along"          "list_merge"          "list_modify"        
## [103] "lmap"                "lmap_at"             "lmap_if"            
## [106] "map"                 "map_at"              "map_call"           
## [109] "map_chr"             "map_dbl"             "map_depth"          
## [112] "map_df"              "map_dfc"             "map_dfr"            
## [115] "map_if"              "map_int"             "map_lgl"            
## [118] "map_raw"             "map2"                "map2_chr"           
## [121] "map2_dbl"            "map2_df"             "map2_dfc"           
## [124] "map2_dfr"            "map2_int"            "map2_lgl"           
## [127] "map2_raw"            "modify"              "modify_at"          
## [130] "modify_depth"        "modify_if"           "modify_in"          
## [133] "modify2"             "negate"              "none"               
## [136] "partial"             "pluck"               "pluck<-"            
## [139] "pmap"                "pmap_chr"            "pmap_dbl"           
## [142] "pmap_df"             "pmap_dfc"            "pmap_dfr"           
## [145] "pmap_int"            "pmap_lgl"            "pmap_raw"           
## [148] "possibly"            "prepend"             "pwalk"              
## [151] "quietly"             "rate_backoff"        "rate_delay"         
## [154] "rate_reset"          "rate_sleep"          "rbernoulli"         
## [157] "rdunif"              "reduce"              "reduce_right"       
## [160] "reduce2"             "reduce2_right"       "rep_along"          
## [163] "rerun"               "safely"              "set_names"          
## [166] "simplify"            "simplify_all"        "slowly"             
## [169] "some"                "splice"              "tail_while"         
## [172] "transpose"           "update_list"         "vec_depth"          
## [175] "walk"                "walk2"               "when"               
## [178] "zap"
lsf.str("package:purrr") # List Objects and their Structure
## %@% : function (x, name)  
## %>% : function (lhs, rhs)  
## %||% : function (x, y)  
## accumulate : function (.x, .f, ..., .init, .dir = c("forward", "backward"))  
## accumulate_right : function (.x, .f, ..., .init)  
## accumulate2 : function (.x, .y, .f, ..., .init)  
## array_branch : function (array, margin = NULL)  
## array_tree : function (array, margin = NULL)  
## as_function : function (...)  
## as_mapper : function (.f, ...)  
## as_vector : function (.x, .type = NULL)  
## assign_in : function (x, where, value)  
## at_depth : function (.x, .depth, .f, ...)  
## attr_getter : function (attr)  
## auto_browse : function (.f)  
## chuck : function (.x, ...)  
## compact : function (.x, .p = identity)  
## compose : function (..., .dir = c("backward", "forward"))  
## cross : function (.l, .filter = NULL)  
## cross_d : function (...)  
## cross_df : function (.l, .filter = NULL)  
## cross_n : function (...)  
## cross2 : function (.x, .y, .filter = NULL)  
## cross3 : function (.x, .y, .z, .filter = NULL)  
## detect : function (.x, .f, ..., .dir = c("forward", "backward"), .right = NULL, 
##     .default = NULL)  
## detect_index : function (.x, .f, ..., .dir = c("forward", "backward"), .right = NULL)  
## discard : function (.x, .p, ...)  
## done : function (x)  
## every : function (.x, .p, ...)  
## exec : function (.fn, ..., .env = caller_env())  
## flatten : function (.x)  
## flatten_chr : function (.x)  
## flatten_dbl : function (.x)  
## flatten_df : function (.x, .id = NULL)  
## flatten_dfc : function (.x)  
## flatten_dfr : function (.x, .id = NULL)  
## flatten_int : function (.x)  
## flatten_lgl : function (.x)  
## flatten_raw : function (.x)  
## has_element : function (.x, .y)  
## head_while : function (.x, .p, ...)  
## imap : function (.x, .f, ...)  
## imap_chr : function (.x, .f, ...)  
## imap_dbl : function (.x, .f, ...)  
## imap_dfc : function (.x, .f, ...)  
## imap_dfr : function (.x, .f, ..., .id = NULL)  
## imap_int : function (.x, .f, ...)  
## imap_lgl : function (.x, .f, ...)  
## imap_raw : function (.x, .f, ...)  
## imodify : function (.x, .f, ...)  
## insistently : function (f, rate = rate_backoff(), quiet = TRUE)  
## invoke : function (.f, .x = NULL, ..., .env = NULL)  
## invoke_map : function (.f, .x = list(NULL), ..., .env = NULL)  
## invoke_map_chr : function (.f, .x = list(NULL), ..., .env = NULL)  
## invoke_map_dbl : function (.f, .x = list(NULL), ..., .env = NULL)  
## invoke_map_df : function (.f, .x = list(NULL), ..., .env = NULL)  
## invoke_map_dfc : function (.f, .x = list(NULL), ..., .env = NULL)  
## invoke_map_dfr : function (.f, .x = list(NULL), ..., .env = NULL)  
## invoke_map_int : function (.f, .x = list(NULL), ..., .env = NULL)  
## invoke_map_lgl : function (.f, .x = list(NULL), ..., .env = NULL)  
## invoke_map_raw : function (.f, .x = list(NULL), ..., .env = NULL)  
## is_atomic : function (x, n = NULL)  
## is_bare_atomic : function (x, n = NULL)  
## is_bare_character : function (x, n = NULL)  
## is_bare_double : function (x, n = NULL)  
## is_bare_integer : function (x, n = NULL)  
## is_bare_list : function (x, n = NULL)  
## is_bare_logical : function (x, n = NULL)  
## is_bare_numeric : function (x, n = NULL)  
## is_bare_vector : function (x, n = NULL)  
## is_character : function (x, n = NULL)  
## is_double : function (x, n = NULL, finite = NULL)  
## is_empty : function (x)  
## is_formula : function (x, scoped = NULL, lhs = NULL)  
## is_function : function (x)  
## is_integer : function (x, n = NULL)  
## is_list : function (x, n = NULL)  
## is_logical : function (x, n = NULL)  
## is_null : function (x)  
## is_numeric : function (x)  
## is_rate : function (x)  
## is_scalar_atomic : function (x)  
## is_scalar_character : function (x)  
## is_scalar_double : function (x)  
## is_scalar_integer : function (x)  
## is_scalar_list : function (x)  
## is_scalar_logical : function (x)  
## is_scalar_numeric : function (x)  
## is_scalar_vector : function (x)  
## is_vector : function (x, n = NULL)  
## iwalk : function (.x, .f, ...)  
## keep : function (.x, .p, ...)  
## lift : function (..f, ..., .unnamed = FALSE)  
## lift_dl : function (..f, ..., .unnamed = FALSE)  
## lift_dv : function (..f, ..., .unnamed = FALSE)  
## lift_ld : function (..f, ...)  
## lift_lv : function (..f, ...)  
## lift_vd : function (..f, ..., .type)  
## lift_vl : function (..f, ..., .type)  
## list_along : function (x)  
## list_merge : function (.x, ...)  
## list_modify : function (.x, ...)  
## lmap : function (.x, .f, ...)  
## lmap_at : function (.x, .at, .f, ...)  
## lmap_if : function (.x, .p, .f, ..., .else = NULL)  
## map : function (.x, .f, ...)  
## map_at : function (.x, .at, .f, ...)  
## map_call : function (.x, .f, ...)  
## map_chr : function (.x, .f, ...)  
## map_dbl : function (.x, .f, ...)  
## map_depth : function (.x, .depth, .f, ..., .ragged = FALSE)  
## map_df : function (.x, .f, ..., .id = NULL)  
## map_dfc : function (.x, .f, ...)  
## map_dfr : function (.x, .f, ..., .id = NULL)  
## map_if : function (.x, .p, .f, ..., .else = NULL)  
## map_int : function (.x, .f, ...)  
## map_lgl : function (.x, .f, ...)  
## map_raw : function (.x, .f, ...)  
## map2 : function (.x, .y, .f, ...)  
## map2_chr : function (.x, .y, .f, ...)  
## map2_dbl : function (.x, .y, .f, ...)  
## map2_df : function (.x, .y, .f, ..., .id = NULL)  
## map2_dfc : function (.x, .y, .f, ...)  
## map2_dfr : function (.x, .y, .f, ..., .id = NULL)  
## map2_int : function (.x, .y, .f, ...)  
## map2_lgl : function (.x, .y, .f, ...)  
## map2_raw : function (.x, .y, .f, ...)  
## modify : function (.x, .f, ...)  
## modify_at : function (.x, .at, .f, ...)  
## modify_depth : function (.x, .depth, .f, ..., .ragged = .depth < 0)  
## modify_if : function (.x, .p, .f, ..., .else = NULL)  
## modify_in : function (.x, .where, .f, ...)  
## modify2 : function (.x, .y, .f, ...)  
## negate : function (.p)  
## none : function (.x, .p, ...)  
## partial : function (.f, ..., .env = NULL, .lazy = NULL, .first = NULL)  
## pluck : function (.x, ..., .default = NULL)  
## pluck<- : function (.x, ..., value)  
## pmap : function (.l, .f, ...)  
## pmap_chr : function (.l, .f, ...)  
## pmap_dbl : function (.l, .f, ...)  
## pmap_df : function (.l, .f, ..., .id = NULL)  
## pmap_dfc : function (.l, .f, ...)  
## pmap_dfr : function (.l, .f, ..., .id = NULL)  
## pmap_int : function (.l, .f, ...)  
## pmap_lgl : function (.l, .f, ...)  
## pmap_raw : function (.l, .f, ...)  
## possibly : function (.f, otherwise, quiet = TRUE)  
## prepend : function (x, values, before = NULL)  
## pwalk : function (.l, .f, ...)  
## quietly : function (.f)  
## rate_backoff : function (pause_base = 1, pause_cap = 60, pause_min = 1, max_times = 3, 
##     jitter = TRUE)  
## rate_delay : function (pause = 1, max_times = Inf)  
## rate_reset : function (rate)  
## rate_sleep : function (rate, quiet = TRUE)  
## rbernoulli : function (n, p = 0.5)  
## rdunif : function (n, b, a = 1)  
## reduce : function (.x, .f, ..., .init, .dir = c("forward", "backward"))  
## reduce_right : function (.x, .f, ..., .init)  
## reduce2 : function (.x, .y, .f, ..., .init)  
## reduce2_right : function (.x, .y, .f, ..., .init)  
## rep_along : function (along, x)  
## rerun : function (.n, ...)  
## safely : function (.f, otherwise = NULL, quiet = TRUE)  
## set_names : function (x, nm = x, ...)  
## simplify : function (.x, .type = NULL)  
## simplify_all : function (.x, .type = NULL)  
## slowly : function (f, rate = rate_delay(), quiet = TRUE)  
## some : function (.x, .p, ...)  
## splice : function (...)  
## tail_while : function (.x, .p, ...)  
## transpose : function (.l, .names = NULL)  
## update_list : function (.x, ...)  
## vec_depth : function (x)  
## walk : function (.x, .f, ...)  
## walk2 : function (.x, .y, .f, ...)  
## when : function (., ...)  
## zap : function ()

包含的内容太多,所以选择一些重要的function进行介绍

map表示映射,可以在一个或多个列表/向量的每个位置上应用相同函数进行计算。map函数的映射对象只有一个。

map(.x, .f, …) .x: 列表或向量; .f: 映射函数; …: 映射函数的其他参数

# 单个向量map,指定函数参数
1:4 %>%
  map(rnorm,mean=1,sd=2)
## [[1]]
## [1] -0.5741208
## 
## [[2]]
## [1] 0.1116946 1.0608781
## 
## [[3]]
## [1] 4.518926 2.606170 2.559288
## 
## [[4]]
## [1] -0.3756527  0.5174267  1.1310676 -2.4495747

map2函数是map函数的变形,映射对象有两个,需要注意两个列表/向量的长度必须相同。

map2(.x,.y, .f, …) .x: 列表或向量; .y: 列表或向量,与.x等长; .f: 映射函数; …: 映射函数的其他参数

# 两个向量map,使用公式函数
map2(1:3,2:4,~sum(.x,.y))
## [[1]]
## [1] 3
## 
## [[2]]
## [1] 5
## 
## [[3]]
## [1] 7

pmap函数是map函数的变形,映射对象为多个,需要注意多个列表/向量的长度必须相同。

pmap(.l, .f, …) .l: 列表向量/列表; .f: 映射函数; …: 映射函数的其他参数

# 多个向量map,使用公式函数
pmap(list(1:3,2:4,3:5),~sum(..1,..2,..3))
## [[1]]
## [1] 6
## 
## [[2]]
## [1] 9
## 
## [[3]]
## [1] 12

调用不同的函数 还有一种更复杂的情况:不但传给函数的参数不同,甚至函数本身也是不同的。

f = c("runif", "rnorm", "rpois")
param = list(
    list(min = -1, max = 1),
    list(sd = 5),
    list(lambda = 10)
)

为了处理这种情况,我们使用invoke_map()函数:

invoke_map(f, param, n = 5)
## [[1]]
## [1]  0.3487803  0.8372930 -0.3171254  0.7508114  0.8994670
## 
## [[2]]
## [1] -6.888394  2.939924  7.346825  8.321915 -6.096242
## 
## [[3]]
## [1] 15 10  5 10  8

第1个参数是一个函数列表或包含函数名称的字符串向量。第2个参数是列表的一个列表,给出了要传给各个函数的不同参数。随后的参数要传给每个函数。

reduce reduce函数表示规约,计算向量中相邻的两个元素,结果再与第三个元素计算,…,最后计算出一个值。

reduce(1:5,paste)
## [1] "1 2 3 4 5"

reduce函数可以有很多的妙用,比如将一系列data.frame,进行left_join

reduce2函数可以同时对两个向量进行规约计算,注意第二个向量长度需要比第一个向量小1。

# 多个向量reduce
reduce2(1:4,c(1,1,1),function(x,y,z) x+y-z)
## [1] 7

计算逻辑为第一次:1+2-1=2,第二次2+3-1=4,第三次4+4-1=7。

函数 accumulate() 与 reduce() 作用方式相同,不同之处是:reduce() 只保留最终的结果,而 accumulate() 会保留所有中间结果。例如,

accumulate(1:100, sum) 
##   [1]    1    3    6   10   15   21   28   36   45   55   66   78   91  105  120
##  [16]  136  153  171  190  210  231  253  276  300  325  351  378  406  435  465
##  [31]  496  528  561  595  630  666  703  741  780  820  861  903  946  990 1035
##  [46] 1081 1128 1176 1225 1275 1326 1378 1431 1485 1540 1596 1653 1711 1770 1830
##  [61] 1891 1953 2016 2080 2145 2211 2278 2346 2415 2485 2556 2628 2701 2775 2850
##  [76] 2926 3003 3081 3160 3240 3321 3403 3486 3570 3655 3741 3828 3916 4005 4095
##  [91] 4186 4278 4371 4465 4560 4656 4753 4851 4950 5050

pluck():同 [[ 提取列表中的元素 keep(): 保留满足条件的元素 dicard(): 删除满足条件的元素 compact(): 删除列表中的空元素 append():在列表末尾增加元素 flatten(): 摊平列表(只摊平一层)

library(tidyverse)
set.seed(42722)
## Names of the example data frames we'll create
## are df_1 ... df5
df_names <- paste0("df_", 1:5) %>% 
  set_names()


df_names
##   df_1   df_2   df_3   df_4   df_5 
## "df_1" "df_2" "df_3" "df_4" "df_5"
## We'll make the new dfs by sampling from mtcars
base_df <- as_tibble(mtcars, rownames = "model") %>% 
  select(model, cyl, hp)

base_df
## # A tibble: 32 x 3
##    model               cyl    hp
##    <chr>             <dbl> <dbl>
##  1 Mazda RX4             6   110
##  2 Mazda RX4 Wag         6   110
##  3 Datsun 710            4    93
##  4 Hornet 4 Drive        6   110
##  5 Hornet Sportabout     8   175
##  6 Valiant               6   105
##  7 Duster 360            8   245
##  8 Merc 240D             4    62
##  9 Merc 230              4    95
## 10 Merc 280              6   123
## # … with 22 more rows
## Create 5 new data frame objects in our environment.
## Each is a sample of ten rows of three columns from mtcars

df_names %>% 
  walk(~ assign(x = .x,         # each element of df_names in turn
                value = sample_n(base_df, 10), 
                envir = .GlobalEnv))
## Now we have, e.g.
df_1
## # A tibble: 10 x 3
##    model               cyl    hp
##    <chr>             <dbl> <dbl>
##  1 Chrysler Imperial     8   230
##  2 Mazda RX4 Wag         6   110
##  3 Merc 450SE            8   180
##  4 Porsche 914-2         4    91
##  5 Toyota Corona         4    97
##  6 Ford Pantera L        8   264
##  7 Toyota Corolla        4    65
##  8 Merc 280C             6   123
##  9 Duster 360            8   245
## 10 Merc 230              4    95
df_2
## # A tibble: 10 x 3
##    model                 cyl    hp
##    <chr>               <dbl> <dbl>
##  1 Toyota Corolla          4    65
##  2 Pontiac Firebird        8   175
##  3 Merc 280                6   123
##  4 Merc 450SE              8   180
##  5 Toyota Corona           4    97
##  6 Lincoln Continental     8   215
##  7 Ferrari Dino            6   175
##  8 Merc 450SLC             8   180
##  9 Dodge Challenger        8   150
## 10 Lotus Europa            4   113
df_names
##   df_1   df_2   df_3   df_4   df_5 
## "df_1" "df_2" "df_3" "df_4" "df_5"
df_list <- map(df_names, get)
df_list
## $df_1
## # A tibble: 10 x 3
##    model               cyl    hp
##    <chr>             <dbl> <dbl>
##  1 Chrysler Imperial     8   230
##  2 Mazda RX4 Wag         6   110
##  3 Merc 450SE            8   180
##  4 Porsche 914-2         4    91
##  5 Toyota Corona         4    97
##  6 Ford Pantera L        8   264
##  7 Toyota Corolla        4    65
##  8 Merc 280C             6   123
##  9 Duster 360            8   245
## 10 Merc 230              4    95
## 
## $df_2
## # A tibble: 10 x 3
##    model                 cyl    hp
##    <chr>               <dbl> <dbl>
##  1 Toyota Corolla          4    65
##  2 Pontiac Firebird        8   175
##  3 Merc 280                6   123
##  4 Merc 450SE              8   180
##  5 Toyota Corona           4    97
##  6 Lincoln Continental     8   215
##  7 Ferrari Dino            6   175
##  8 Merc 450SLC             8   180
##  9 Dodge Challenger        8   150
## 10 Lotus Europa            4   113
## 
## $df_3
## # A tibble: 10 x 3
##    model                cyl    hp
##    <chr>              <dbl> <dbl>
##  1 Fiat 128               4    66
##  2 Hornet 4 Drive         6   110
##  3 Fiat X1-9              4    66
##  4 Hornet Sportabout      8   175
##  5 Maserati Bora          8   335
##  6 Merc 230               4    95
##  7 Valiant                6   105
##  8 Mazda RX4 Wag          6   110
##  9 Toyota Corona          4    97
## 10 Cadillac Fleetwood     8   205
## 
## $df_4
## # A tibble: 10 x 3
##    model               cyl    hp
##    <chr>             <dbl> <dbl>
##  1 Fiat X1-9             4    66
##  2 AMC Javelin           8   150
##  3 Chrysler Imperial     8   230
##  4 Valiant               6   105
##  5 Hornet Sportabout     8   175
##  6 Merc 240D             4    62
##  7 Merc 280              6   123
##  8 Mazda RX4 Wag         6   110
##  9 Lotus Europa          4   113
## 10 Hornet 4 Drive        6   110
## 
## $df_5
## # A tibble: 10 x 3
##    model                cyl    hp
##    <chr>              <dbl> <dbl>
##  1 Chrysler Imperial      8   230
##  2 Porsche 914-2          4    91
##  3 Camaro Z28             8   245
##  4 Merc 450SL             8   180
##  5 Toyota Corona          4    97
##  6 Hornet 4 Drive         6   110
##  7 Cadillac Fleetwood     8   205
##  8 Merc 280C              6   123
##  9 Toyota Corolla         4    65
## 10 Pontiac Firebird       8   175
split_list <- df_list %>% 
  map(~ mutate(., 
               over_under = if_else(.$cyl > 5, "over", "under"))) %>% 
    map(~ split(., as.factor(.$over_under))) 


split_list
## $df_1
## $df_1$over
## # A tibble: 6 x 4
##   model               cyl    hp over_under
##   <chr>             <dbl> <dbl> <chr>     
## 1 Chrysler Imperial     8   230 over      
## 2 Mazda RX4 Wag         6   110 over      
## 3 Merc 450SE            8   180 over      
## 4 Ford Pantera L        8   264 over      
## 5 Merc 280C             6   123 over      
## 6 Duster 360            8   245 over      
## 
## $df_1$under
## # A tibble: 4 x 4
##   model            cyl    hp over_under
##   <chr>          <dbl> <dbl> <chr>     
## 1 Porsche 914-2      4    91 under     
## 2 Toyota Corona      4    97 under     
## 3 Toyota Corolla     4    65 under     
## 4 Merc 230           4    95 under     
## 
## 
## $df_2
## $df_2$over
## # A tibble: 7 x 4
##   model                 cyl    hp over_under
##   <chr>               <dbl> <dbl> <chr>     
## 1 Pontiac Firebird        8   175 over      
## 2 Merc 280                6   123 over      
## 3 Merc 450SE              8   180 over      
## 4 Lincoln Continental     8   215 over      
## 5 Ferrari Dino            6   175 over      
## 6 Merc 450SLC             8   180 over      
## 7 Dodge Challenger        8   150 over      
## 
## $df_2$under
## # A tibble: 3 x 4
##   model            cyl    hp over_under
##   <chr>          <dbl> <dbl> <chr>     
## 1 Toyota Corolla     4    65 under     
## 2 Toyota Corona      4    97 under     
## 3 Lotus Europa       4   113 under     
## 
## 
## $df_3
## $df_3$over
## # A tibble: 6 x 4
##   model                cyl    hp over_under
##   <chr>              <dbl> <dbl> <chr>     
## 1 Hornet 4 Drive         6   110 over      
## 2 Hornet Sportabout      8   175 over      
## 3 Maserati Bora          8   335 over      
## 4 Valiant                6   105 over      
## 5 Mazda RX4 Wag          6   110 over      
## 6 Cadillac Fleetwood     8   205 over      
## 
## $df_3$under
## # A tibble: 4 x 4
##   model           cyl    hp over_under
##   <chr>         <dbl> <dbl> <chr>     
## 1 Fiat 128          4    66 under     
## 2 Fiat X1-9         4    66 under     
## 3 Merc 230          4    95 under     
## 4 Toyota Corona     4    97 under     
## 
## 
## $df_4
## $df_4$over
## # A tibble: 7 x 4
##   model               cyl    hp over_under
##   <chr>             <dbl> <dbl> <chr>     
## 1 AMC Javelin           8   150 over      
## 2 Chrysler Imperial     8   230 over      
## 3 Valiant               6   105 over      
## 4 Hornet Sportabout     8   175 over      
## 5 Merc 280              6   123 over      
## 6 Mazda RX4 Wag         6   110 over      
## 7 Hornet 4 Drive        6   110 over      
## 
## $df_4$under
## # A tibble: 3 x 4
##   model          cyl    hp over_under
##   <chr>        <dbl> <dbl> <chr>     
## 1 Fiat X1-9        4    66 under     
## 2 Merc 240D        4    62 under     
## 3 Lotus Europa     4   113 under     
## 
## 
## $df_5
## $df_5$over
## # A tibble: 7 x 4
##   model                cyl    hp over_under
##   <chr>              <dbl> <dbl> <chr>     
## 1 Chrysler Imperial      8   230 over      
## 2 Camaro Z28             8   245 over      
## 3 Merc 450SL             8   180 over      
## 4 Hornet 4 Drive         6   110 over      
## 5 Cadillac Fleetwood     8   205 over      
## 6 Merc 280C              6   123 over      
## 7 Pontiac Firebird       8   175 over      
## 
## $df_5$under
## # A tibble: 3 x 4
##   model            cyl    hp over_under
##   <chr>          <dbl> <dbl> <chr>     
## 1 Porsche 914-2      4    91 under     
## 2 Toyota Corona      4    97 under     
## 3 Toyota Corolla     4    65 under
df_list %>% 
  map(~ mutate(., 
               over_under = if_else(.$cyl > 5, "over", "under")))
## $df_1
## # A tibble: 10 x 4
##    model               cyl    hp over_under
##    <chr>             <dbl> <dbl> <chr>     
##  1 Chrysler Imperial     8   230 over      
##  2 Mazda RX4 Wag         6   110 over      
##  3 Merc 450SE            8   180 over      
##  4 Porsche 914-2         4    91 under     
##  5 Toyota Corona         4    97 under     
##  6 Ford Pantera L        8   264 over      
##  7 Toyota Corolla        4    65 under     
##  8 Merc 280C             6   123 over      
##  9 Duster 360            8   245 over      
## 10 Merc 230              4    95 under     
## 
## $df_2
## # A tibble: 10 x 4
##    model                 cyl    hp over_under
##    <chr>               <dbl> <dbl> <chr>     
##  1 Toyota Corolla          4    65 under     
##  2 Pontiac Firebird        8   175 over      
##  3 Merc 280                6   123 over      
##  4 Merc 450SE              8   180 over      
##  5 Toyota Corona           4    97 under     
##  6 Lincoln Continental     8   215 over      
##  7 Ferrari Dino            6   175 over      
##  8 Merc 450SLC             8   180 over      
##  9 Dodge Challenger        8   150 over      
## 10 Lotus Europa            4   113 under     
## 
## $df_3
## # A tibble: 10 x 4
##    model                cyl    hp over_under
##    <chr>              <dbl> <dbl> <chr>     
##  1 Fiat 128               4    66 under     
##  2 Hornet 4 Drive         6   110 over      
##  3 Fiat X1-9              4    66 under     
##  4 Hornet Sportabout      8   175 over      
##  5 Maserati Bora          8   335 over      
##  6 Merc 230               4    95 under     
##  7 Valiant                6   105 over      
##  8 Mazda RX4 Wag          6   110 over      
##  9 Toyota Corona          4    97 under     
## 10 Cadillac Fleetwood     8   205 over      
## 
## $df_4
## # A tibble: 10 x 4
##    model               cyl    hp over_under
##    <chr>             <dbl> <dbl> <chr>     
##  1 Fiat X1-9             4    66 under     
##  2 AMC Javelin           8   150 over      
##  3 Chrysler Imperial     8   230 over      
##  4 Valiant               6   105 over      
##  5 Hornet Sportabout     8   175 over      
##  6 Merc 240D             4    62 under     
##  7 Merc 280              6   123 over      
##  8 Mazda RX4 Wag         6   110 over      
##  9 Lotus Europa          4   113 under     
## 10 Hornet 4 Drive        6   110 over      
## 
## $df_5
## # A tibble: 10 x 4
##    model                cyl    hp over_under
##    <chr>              <dbl> <dbl> <chr>     
##  1 Chrysler Imperial      8   230 over      
##  2 Porsche 914-2          4    91 under     
##  3 Camaro Z28             8   245 over      
##  4 Merc 450SL             8   180 over      
##  5 Toyota Corona          4    97 under     
##  6 Hornet 4 Drive         6   110 over      
##  7 Cadillac Fleetwood     8   205 over      
##  8 Merc 280C              6   123 over      
##  9 Toyota Corolla         4    65 under     
## 10 Pontiac Firebird       8   175 over

The . inside the mutate() and split() functions are pronouns standing for “the thing we’re referring to/computing on right now”. In this case, that’s “the current data frame as we iterate through df_list”. Now we have a nested list. Each of df_1 to df_5 is split into an over or under table. The whole thing looks like this:

split_list %>% 
  map("over") %>%                               # subset to "over" dfs only
  set_names(nm = ~ paste0(.x, "_over")) %>%     # name each element, add the _over suffix
  walk2(.x = names(.), #                        # write out each df with its name
        .y = .,
        .f = ~ assign(x = .x,
                value = as_tibble(.y),
                envir = .GlobalEnv))

split_list
## $df_1
## $df_1$over
## # A tibble: 6 x 4
##   model               cyl    hp over_under
##   <chr>             <dbl> <dbl> <chr>     
## 1 Chrysler Imperial     8   230 over      
## 2 Mazda RX4 Wag         6   110 over      
## 3 Merc 450SE            8   180 over      
## 4 Ford Pantera L        8   264 over      
## 5 Merc 280C             6   123 over      
## 6 Duster 360            8   245 over      
## 
## $df_1$under
## # A tibble: 4 x 4
##   model            cyl    hp over_under
##   <chr>          <dbl> <dbl> <chr>     
## 1 Porsche 914-2      4    91 under     
## 2 Toyota Corona      4    97 under     
## 3 Toyota Corolla     4    65 under     
## 4 Merc 230           4    95 under     
## 
## 
## $df_2
## $df_2$over
## # A tibble: 7 x 4
##   model                 cyl    hp over_under
##   <chr>               <dbl> <dbl> <chr>     
## 1 Pontiac Firebird        8   175 over      
## 2 Merc 280                6   123 over      
## 3 Merc 450SE              8   180 over      
## 4 Lincoln Continental     8   215 over      
## 5 Ferrari Dino            6   175 over      
## 6 Merc 450SLC             8   180 over      
## 7 Dodge Challenger        8   150 over      
## 
## $df_2$under
## # A tibble: 3 x 4
##   model            cyl    hp over_under
##   <chr>          <dbl> <dbl> <chr>     
## 1 Toyota Corolla     4    65 under     
## 2 Toyota Corona      4    97 under     
## 3 Lotus Europa       4   113 under     
## 
## 
## $df_3
## $df_3$over
## # A tibble: 6 x 4
##   model                cyl    hp over_under
##   <chr>              <dbl> <dbl> <chr>     
## 1 Hornet 4 Drive         6   110 over      
## 2 Hornet Sportabout      8   175 over      
## 3 Maserati Bora          8   335 over      
## 4 Valiant                6   105 over      
## 5 Mazda RX4 Wag          6   110 over      
## 6 Cadillac Fleetwood     8   205 over      
## 
## $df_3$under
## # A tibble: 4 x 4
##   model           cyl    hp over_under
##   <chr>         <dbl> <dbl> <chr>     
## 1 Fiat 128          4    66 under     
## 2 Fiat X1-9         4    66 under     
## 3 Merc 230          4    95 under     
## 4 Toyota Corona     4    97 under     
## 
## 
## $df_4
## $df_4$over
## # A tibble: 7 x 4
##   model               cyl    hp over_under
##   <chr>             <dbl> <dbl> <chr>     
## 1 AMC Javelin           8   150 over      
## 2 Chrysler Imperial     8   230 over      
## 3 Valiant               6   105 over      
## 4 Hornet Sportabout     8   175 over      
## 5 Merc 280              6   123 over      
## 6 Mazda RX4 Wag         6   110 over      
## 7 Hornet 4 Drive        6   110 over      
## 
## $df_4$under
## # A tibble: 3 x 4
##   model          cyl    hp over_under
##   <chr>        <dbl> <dbl> <chr>     
## 1 Fiat X1-9        4    66 under     
## 2 Merc 240D        4    62 under     
## 3 Lotus Europa     4   113 under     
## 
## 
## $df_5
## $df_5$over
## # A tibble: 7 x 4
##   model                cyl    hp over_under
##   <chr>              <dbl> <dbl> <chr>     
## 1 Chrysler Imperial      8   230 over      
## 2 Camaro Z28             8   245 over      
## 3 Merc 450SL             8   180 over      
## 4 Hornet 4 Drive         6   110 over      
## 5 Cadillac Fleetwood     8   205 over      
## 6 Merc 280C              6   123 over      
## 7 Pontiac Firebird       8   175 over      
## 
## $df_5$under
## # A tibble: 3 x 4
##   model            cyl    hp over_under
##   <chr>          <dbl> <dbl> <chr>     
## 1 Porsche 914-2      4    91 under     
## 2 Toyota Corona      4    97 under     
## 3 Toyota Corolla     4    65 under
lapply(split_list, `[[`, "over")
## $df_1
## # A tibble: 6 x 4
##   model               cyl    hp over_under
##   <chr>             <dbl> <dbl> <chr>     
## 1 Chrysler Imperial     8   230 over      
## 2 Mazda RX4 Wag         6   110 over      
## 3 Merc 450SE            8   180 over      
## 4 Ford Pantera L        8   264 over      
## 5 Merc 280C             6   123 over      
## 6 Duster 360            8   245 over      
## 
## $df_2
## # A tibble: 7 x 4
##   model                 cyl    hp over_under
##   <chr>               <dbl> <dbl> <chr>     
## 1 Pontiac Firebird        8   175 over      
## 2 Merc 280                6   123 over      
## 3 Merc 450SE              8   180 over      
## 4 Lincoln Continental     8   215 over      
## 5 Ferrari Dino            6   175 over      
## 6 Merc 450SLC             8   180 over      
## 7 Dodge Challenger        8   150 over      
## 
## $df_3
## # A tibble: 6 x 4
##   model                cyl    hp over_under
##   <chr>              <dbl> <dbl> <chr>     
## 1 Hornet 4 Drive         6   110 over      
## 2 Hornet Sportabout      8   175 over      
## 3 Maserati Bora          8   335 over      
## 4 Valiant                6   105 over      
## 5 Mazda RX4 Wag          6   110 over      
## 6 Cadillac Fleetwood     8   205 over      
## 
## $df_4
## # A tibble: 7 x 4
##   model               cyl    hp over_under
##   <chr>             <dbl> <dbl> <chr>     
## 1 AMC Javelin           8   150 over      
## 2 Chrysler Imperial     8   230 over      
## 3 Valiant               6   105 over      
## 4 Hornet Sportabout     8   175 over      
## 5 Merc 280              6   123 over      
## 6 Mazda RX4 Wag         6   110 over      
## 7 Hornet 4 Drive        6   110 over      
## 
## $df_5
## # A tibble: 7 x 4
##   model                cyl    hp over_under
##   <chr>              <dbl> <dbl> <chr>     
## 1 Chrysler Imperial      8   230 over      
## 2 Camaro Z28             8   245 over      
## 3 Merc 450SL             8   180 over      
## 4 Hornet 4 Drive         6   110 over      
## 5 Cadillac Fleetwood     8   205 over      
## 6 Merc 280C              6   123 over      
## 7 Pontiac Firebird       8   175 over
df_list
## $df_1
## # A tibble: 10 x 3
##    model               cyl    hp
##    <chr>             <dbl> <dbl>
##  1 Chrysler Imperial     8   230
##  2 Mazda RX4 Wag         6   110
##  3 Merc 450SE            8   180
##  4 Porsche 914-2         4    91
##  5 Toyota Corona         4    97
##  6 Ford Pantera L        8   264
##  7 Toyota Corolla        4    65
##  8 Merc 280C             6   123
##  9 Duster 360            8   245
## 10 Merc 230              4    95
## 
## $df_2
## # A tibble: 10 x 3
##    model                 cyl    hp
##    <chr>               <dbl> <dbl>
##  1 Toyota Corolla          4    65
##  2 Pontiac Firebird        8   175
##  3 Merc 280                6   123
##  4 Merc 450SE              8   180
##  5 Toyota Corona           4    97
##  6 Lincoln Continental     8   215
##  7 Ferrari Dino            6   175
##  8 Merc 450SLC             8   180
##  9 Dodge Challenger        8   150
## 10 Lotus Europa            4   113
## 
## $df_3
## # A tibble: 10 x 3
##    model                cyl    hp
##    <chr>              <dbl> <dbl>
##  1 Fiat 128               4    66
##  2 Hornet 4 Drive         6   110
##  3 Fiat X1-9              4    66
##  4 Hornet Sportabout      8   175
##  5 Maserati Bora          8   335
##  6 Merc 230               4    95
##  7 Valiant                6   105
##  8 Mazda RX4 Wag          6   110
##  9 Toyota Corona          4    97
## 10 Cadillac Fleetwood     8   205
## 
## $df_4
## # A tibble: 10 x 3
##    model               cyl    hp
##    <chr>             <dbl> <dbl>
##  1 Fiat X1-9             4    66
##  2 AMC Javelin           8   150
##  3 Chrysler Imperial     8   230
##  4 Valiant               6   105
##  5 Hornet Sportabout     8   175
##  6 Merc 240D             4    62
##  7 Merc 280              6   123
##  8 Mazda RX4 Wag         6   110
##  9 Lotus Europa          4   113
## 10 Hornet 4 Drive        6   110
## 
## $df_5
## # A tibble: 10 x 3
##    model                cyl    hp
##    <chr>              <dbl> <dbl>
##  1 Chrysler Imperial      8   230
##  2 Porsche 914-2          4    91
##  3 Camaro Z28             8   245
##  4 Merc 450SL             8   180
##  5 Toyota Corona          4    97
##  6 Hornet 4 Drive         6   110
##  7 Cadillac Fleetwood     8   205
##  8 Merc 280C              6   123
##  9 Toyota Corolla         4    65
## 10 Pontiac Firebird       8   175
df_all <- bind_rows(df_list, .id = "id")
df_all
## # A tibble: 50 x 4
##    id    model               cyl    hp
##    <chr> <chr>             <dbl> <dbl>
##  1 df_1  Chrysler Imperial     8   230
##  2 df_1  Mazda RX4 Wag         6   110
##  3 df_1  Merc 450SE            8   180
##  4 df_1  Porsche 914-2         4    91
##  5 df_1  Toyota Corona         4    97
##  6 df_1  Ford Pantera L        8   264
##  7 df_1  Toyota Corolla        4    65
##  8 df_1  Merc 280C             6   123
##  9 df_1  Duster 360            8   245
## 10 df_1  Merc 230              4    95
## # … with 40 more rows

最后一次修改于 2022-05-17