R语言--map与reduce

作者: FTDdata | 来源:发表于2021-04-13 09:16 被阅读0次

    map(映射)与reduce(规约)操作在数据处理中非常常见,R语言的核心是向量化操作,自带的apply系列函数完成了数据框的向量化计算,而purrr包中的map与reduce系列函数很好的拓展了向量化计算,使R语言处理数据更加优雅流畅。

    purrr包是tidyverse系列中的包,开发者是大名鼎鼎的Hadley Wickham。purrr包中的函数很多,使用最多的是mapreduce系列函数。

    安装包

    install.packages('purrr')
    

    map

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

    map.png

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

    # 加载包
    library(purrr)
    # 单个向量map
    1:4 %>%
      map(rnorm)
    
    ## [[1]]
    ## [1] 0.1892454
    ## 
    ## [[2]]
    ## [1] -1.149757  1.782667
    ## 
    ## [[3]]
    ## [1] 0.9311241 0.5962078 0.8575180
    ## 
    ## [[4]]
    ## [1]  1.2708588  0.7957794 -0.0106283  0.5393979
    

    map函数的结果来看,其返回与输入向量等长的结果,类型为列表

    其他参数

    可以指定映射函数的其他参数:

    # 单个向量map,指定函数参数
    1:4 %>%
      map(rnorm,mean=1,sd=2)
    
    ## [[1]]
    ## [1] 1.610763
    ## 
    ## [[2]]
    ## [1] -0.4034499  1.5814313
    ## 
    ## [[3]]
    ## [1] 2.806429 1.719962 2.005490
    ## 
    ## [[4]]
    ## [1] 2.170663 2.849836 1.085069 4.130320
    

    匿名函数

    传入的函数可以是匿名函数:

    # 单个向量map,使用匿名函数
    1:4 %>%
      map(function(x) rnorm(x))
    
    ## [[1]]
    ## [1] 0.01422782
    ## 
    ## [[2]]
    ## [1] 1.7895586 0.7135593
    ## 
    ## [[3]]
    ## [1]  0.0603224  1.0498781 -1.0028828
    ## 
    ## [[4]]
    ## [1]  0.2673761 -1.1297717  0.7769814  1.5304043
    

    公式函数

    还可以把函数当成一个公式传入,这是purrr提供的高级功能,能够简化代码量。

    • 当函数只有一个参数时,公式函数中用.x代替参数;
    • 当函数有两个参数时,公式函数中用.x,.y代替参数;
    • 当函数有多个参数时,公式函数中用..1,..2,..3代替参数。
    # 单个向量map,使用公式函数
    1:4 %>%
      map(~rnorm(.x))
    
    ## [[1]]
    ## [1] -1.471681
    ## 
    ## [[2]]
    ## [1] -0.04243286 -0.68348293
    ## 
    ## [[3]]
    ## [1]  1.613470 -0.750001 -1.278718
    ## 
    ## [[4]]
    ## [1]  0.9369563 -0.5285622  0.8601058  1.8868754
    

    map2

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

    map2.png

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

    # 两个向量map
    map2(1:3,2:4,sum)
    
    ## [[1]]
    ## [1] 3
    ## 
    ## [[2]]
    ## [1] 5
    ## 
    ## [[3]]
    ## [1] 7
    

    用公式函数的方式:

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

    pmap

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

    pmap.png

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

    # 多个向量map
    pmap(list(1:3,2:4,3:5),sum)
    
    ## [[1]]
    ## [1] 6
    ## 
    ## [[2]]
    ## [1] 9
    ## 
    ## [[3]]
    ## [1] 12
    

    用公式函数的方式:

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

    map变形

    map,map2pmap返回的数据格式都是列表,有时候需要对返回的结果进行数据格式转换,这时候可以直接使用map系列的变形函数,直接一步完成。

    # 返回列表
    map(mtcars,mean)
    
    ## $mpg
    ## [1] 20.09062
    ## 
    ## $cyl
    ## [1] 6.1875
    ## 
    ## $disp
    ## [1] 230.7219
    ## 
    ## $hp
    ## [1] 146.6875
    ## 
    ## $drat
    ## [1] 3.596563
    ## 
    ## $wt
    ## [1] 3.21725
    ## 
    ## $qsec
    ## [1] 17.84875
    ## 
    ## $vs
    ## [1] 0.4375
    ## 
    ## $am
    ## [1] 0.40625
    ## 
    ## $gear
    ## [1] 3.6875
    ## 
    ## $carb
    ## [1] 2.8125
    

    使用map_df函数,直接返回数据框格式。

    # 返回数据框
    map_df(mtcars,mean)
    
    ## # A tibble: 1 x 11
    ##     mpg   cyl  disp    hp  drat    wt  qsec    vs    am  gear  carb
    ##   <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
    ## 1  20.1  6.19  231.  147.  3.60  3.22  17.8 0.438 0.406  3.69  2.81
    
    # 返回字符向量
    map_chr(mtcars,mean)
    
    ##          mpg          cyl         disp           hp         drat           wt 
    ##  "20.090625"   "6.187500" "230.721875" "146.687500"   "3.596563"   "3.217250" 
    ##         qsec           vs           am         gear         carb 
    ##  "17.848750"   "0.437500"   "0.406250"   "3.687500"   "2.812500"
    

    其他的有:

    • map_lgl/map2_lgl/pmap_lgl:返回逻辑向量;
    • map_int/map2_int/pmap_int:返回整数向量;
    • map_dbl/map2_dbl/pmap_dbl:返回浮点数向量;
    • map_chr/map2_chr/pmap_chr:返回字符串向量。

    reduce

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

    reduce.png

    reduce(.x, .f, ...)
    .x: 列表向量/列表;
    .f: 规约函数;
    ...: 函数的其他参数

    # 单个向量reduce
    reduce(1:5,paste)
    
    ## [1] "1 2 3 4 5"
    

    reduce2

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

    reduce2(.x, .y,.f, ...)
    .x: 列表向量/列表;
    .y: 列表向量/列表,长度比.x小1;
    .f: 规约函数;
    ...: 函数的其他参数

    # 多个向量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。

    更多的purrr包中函数用法,可以参考:cheatsheet

    相关文章

      网友评论

        本文标题:R语言--map与reduce

        本文链接:https://www.haomeiwen.com/subject/drjbhltx.html