美文网首页
2019-09-30自建函数用于数据分析

2019-09-30自建函数用于数据分析

作者: iColors | 来源:发表于2019-09-30 09:20 被阅读0次

    原文https://www.njtierney.com/post/2019/09/29/unexpected-function/

    1.R语言允许使用函数作为参数。
    2.在一个函数内部的函数可以自行修改。

    啥意思呢?先创建一个自己的函数:

    my_fun <- function(x, fun){
      fun(x)
    }
    

    现在可以输入任何函数作为这个函数的参数。
    以'dplyr'包的stroms数据为例。

    library(dplyr)
    ## 
    ## Attaching package: 'dplyr'
    ## The following objects are masked from 'package:stats':
    ## 
    ##     filter, lag
    ## The following objects are masked from 'package:base':
    ## 
    ##     intersect, setdiff, setequal, union
    storms
    ## # A tibble: 10,010 x 13
    ##    name   year month   day  hour   lat  long status category  wind pressure
    ##    <chr> <dbl> <dbl> <int> <dbl> <dbl> <dbl> <chr>  <ord>    <int>    <int>
    ##  1 Amy    1975     6    27     0  27.5 -79   tropi… -1          25     1013
    ##  2 Amy    1975     6    27     6  28.5 -79   tropi… -1          25     1013
    ##  3 Amy    1975     6    27    12  29.5 -79   tropi… -1          25     1013
    ##  4 Amy    1975     6    27    18  30.5 -79   tropi… -1          25     1013
    ##  5 Amy    1975     6    28     0  31.5 -78.8 tropi… -1          25     1012
    ##  6 Amy    1975     6    28     6  32.4 -78.7 tropi… -1          25     1012
    ##  7 Amy    1975     6    28    12  33.3 -78   tropi… -1          25     1011
    ##  8 Amy    1975     6    28    18  34   -77   tropi… -1          30     1006
    ##  9 Amy    1975     6    29     0  34.4 -75.8 tropi… 0           35     1004
    ## 10 Amy    1975     6    29     6  34   -74.8 tropi… 0           40     1002
    ## # … with 10,000 more rows, and 2 more variables: ts_diameter <dbl>,
    ## #   hu_diameter <dbl>
    

    计算wind的均值:

    my_fun(storms$wind, mean)
    ## [1] 53.495
    

    也可以计算标准差、变异系数、中位数

    my_fun(storms$wind, sd)
    ## [1] 26.21387
    my_fun(storms$wind, var)
    ## [1] 687.1668
    my_fun(storms$wind, median)
    ## [1] 45
    

    更进一步,如果你想为按月汇总storms的数据,怎么办?

    storms %>% 
      group_by(month) %>%
      summarise(wind_summary = mean(wind))
    ## # A tibble: 10 x 2
    ##    month wind_summary
    ##    <dbl>        <dbl>
    ##  1     1         45.7
    ##  2     4         44.6
    ##  3     5         36.3
    ##  4     6         37.8
    ##  5     7         41.2
    ##  6     8         52.1
    ##  7     9         58.0
    ##  8    10         54.6
    ##  9    11         52.5
    ## 10    12         47.9
    

    可以重复代码,把平均值函数改成其他函数就可以了,比如sd值。

    storms %>% 
      group_by(month) %>%
      summarise(wind_summary = sd(wind))
    ## # A tibble: 10 x 2
    ##    month wind_summary
    ##    <dbl>        <dbl>
    ##  1     1         9.08
    ##  2     4         5.94
    ##  3     5         9.57
    ##  4     6        13.4 
    ##  5     7        19.1 
    ##  6     8        26.0 
    ##  7     9        28.2 
    ##  8    10        25.3 
    ##  9    11        22.0 
    ## 10    12        14.6
    

    如此反复,周而复始,大脑感到很是乏累,有一个声音在脑海中响起:“别像猪一样”。
    为了避免反复带来的麻烦,自己创建一个计算平均值的函数:

    storms_wind_summary <- function(fun){
      storms %>%
        group_by(month) %>%
        summarise(wind_summary = fun(wind))
    }
    

    现在就可以轻松传递函数名字给我们自己建立的函数了,比如mean:

    storms_wind_summary(mean)
    ## # A tibble: 10 x 2
    ##    month wind_summary
    ##    <dbl>        <dbl>
    ##  1     1         45.7
    ##  2     4         44.6
    ##  3     5         36.3
    ##  4     6         37.8
    ##  5     7         41.2
    ##  6     8         52.1
    ##  7     9         58.0
    ##  8    10         54.6
    ##  9    11         52.5
    ## 10    12         47.9
    

    或者其他任何函数:

    storms_wind_summary(sd)
    ## # A tibble: 10 x 2
    ##    month wind_summary
    ##    <dbl>        <dbl>
    ##  1     1         9.08
    ##  2     4         5.94
    ##  3     5         9.57
    ##  4     6        13.4 
    ##  5     7        19.1 
    ##  6     8        26.0 
    ##  7     9        28.2 
    ##  8    10        25.3 
    ##  9    11        22.0 
    ## 10    12        14.6
    storms_wind_summary(var)
    ## # A tibble: 10 x 2
    ##    month wind_summary
    ##    <dbl>        <dbl>
    ##  1     1         82.5
    ##  2     4         35.3
    ##  3     5         91.5
    ##  4     6        180. 
    ##  5     7        365. 
    ##  6     8        678. 
    ##  7     9        793. 
    ##  8    10        638. 
    ##  9    11        482. 
    ## 10    12        213.
    storms_wind_summary(median)
    ## # A tibble: 10 x 2
    ##    month wind_summary
    ##    <dbl>        <dbl>
    ##  1     1         50  
    ##  2     4         45  
    ##  3     5         35  
    ##  4     6         35  
    ##  5     7         37.5
    ##  6     8         45  
    ##  7     9         50  
    ##  8    10         50  
    ##  9    11         50  
    ## 10    12         45
    

    甚至传递自己建立的函数为参数:

    range_diff <- function(x){
      diff(range(x))
    }
      
    storms_wind_summary(range_diff)
    ## # A tibble: 10 x 2
    ##    month wind_summary
    ##    <dbl>        <int>
    ##  1     1           25
    ##  2     4           15
    ##  3     5           35
    ##  4     6           70
    ##  5     7          130
    ##  6     8          140
    ##  7     9          145
    ##  8    10          145
    ##  9    11          120
    ## 10    12           50
    

    怎么样,看起来不错吧。自己就可以操纵函数。

    更上一层楼

    可以用summarise_at实现相同的目的:

    storms_wind_summary <- function(fun){
      storms %>%
        group_by(month) %>%
        summarise_at(.vars = vars(wind),
                     .funs = list(fun))
    }
    
    storms_wind_summary(mean)
    ## # A tibble: 10 x 2
    ##    month  wind
    ##    <dbl> <dbl>
    ##  1     1  45.7
    ##  2     4  44.6
    ##  3     5  36.3
    ##  4     6  37.8
    ##  5     7  41.2
    ##  6     8  52.1
    ##  7     9  58.0
    ##  8    10  54.6
    ##  9    11  52.5
    ## 10    12  47.9
    storms_wind_summary(median)
    ## # A tibble: 10 x 2
    ##    month  wind
    ##    <dbl> <dbl>
    ##  1     1  50  
    ##  2     4  45  
    ##  3     5  35  
    ##  4     6  35  
    ##  5     7  37.5
    ##  6     8  45  
    ##  7     9  50  
    ##  8    10  50  
    ##  9    11  50  
    ## 10    12  45
    

    如果想传递许多函数,比如同时计算mean、median、sd、variance,怎么办?
    可以用...来传递给函数,允许输入任何数目的函数为参数:

    storms_wind_summary <- function(...){
      storms %>%
        group_by(month) %>%
        summarise_at(.vars = vars(wind),
                     .funs = list(...))
    }
    
    
    storms_wind_summary(median, mean, max)
    ## # A tibble: 10 x 4
    ##    month   fn1   fn2   fn3
    ##    <dbl> <dbl> <dbl> <int>
    ##  1     1  50    45.7    55
    ##  2     4  45    44.6    50
    ##  3     5  35    36.3    60
    ##  4     6  35    37.8    80
    ##  5     7  37.5  41.2   140
    ##  6     8  45    52.1   150
    ##  7     9  50    58.0   160
    ##  8    10  50    54.6   160
    ##  9    11  50    52.5   135
    ## 10    12  45    47.9    75
    
    这些技巧虽然简单,在数据分析中经常会用到,灵活掌握就能提高工作效率,减少不必要的重复劳动!!!

    相关文章

      网友评论

          本文标题:2019-09-30自建函数用于数据分析

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