育种数据分析之放飞自我分享 http://blog.sciencenet.cn/u/yijiaobai 关注:生物统计,数量遗传,混合线性模型,生物信息,R,Perl,Python,GWAS,GS相关方法,文章及代码

博文

R语言循环第三境界:purrr包map函数!

已有 498 次阅读 2021-6-10 21:28 |个人分类:农学统计|系统分类:科研笔记

1. 三境界

人和狗.png

R语言写循环有三境界:

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

其中,手动for循环我最常用,apply系列半吊子,purrr函数越用越趁手,这里介绍一下purrr编写循环的方法。

2. 泛函式函数

「泛函式定义:」

函数的函数称为泛函式,map(x,f)中,map是函数,f也是函数,f是map的参数,那么map就是泛函数。

dat = data.frame(y1 = rnorm(10),y2 = rnorm(10)+10)
dat
map(dat,mean)

这里,map是函数,meanmap的参数。

3. 走两步

「测试数据:」

> dat = data.frame(y1 = rnorm(10),y2 = rnorm(10)+10)
> dat
           y1        y2
1  -0.4535438 10.383757
2   0.7821634 11.186901
3   2.0556094  9.382660
4   1.0848204  8.713453
5  -1.4152480 12.927827
6  -0.2379161  9.938319
7  -1.3191011  9.281052
8   0.4194484 10.323932
9   1.4207450 10.142454
10 -0.1421450 11.015331

「任务:」

计算y1和y2两列的平均值

4. 第一境界:for循环

for循环,是编程语言中都有的功能,因为for循环在R语言中速度较慢被各种嫌弃,但是它简单易用,容易理解,所以我写函数时,经常使用for循环镶嵌for循环,乐此不疲。

「看代码:」

re = list() #1
for(i in 1:2){ #2
  re[[i]] = mean(dat[,i]) #3
} #4
re #5

代码解释:

  • 1,将结果赋值给re,所以先定义一个re的列表,为空
  • 2,因为是两列,所以是1:2
  • 3,分别计算平均数
  • 4,循环结束
  • 5,打印结果re

5. 第二境界:apply家族

apply是一套函数,有很多相关的函数,举几个applylapplysapplyvapplymapplytapplyrapplyeapply,我曾经认真的被劝退了好几次,因为理解得不透测,我认为R语言学到apply家族就是我的职业生涯的结束。

工作第二年,我开始学习apply家族函数,工作第10年,我还在学习apply家族函数。

「代码:」

> apply(dat,2,mean)
        y1         y2 
 0.2194833 10.3295686
  • dat为数据
  • 第二个为参数
    • 1表示按照行
    • 2表示按照列
  • mean为平均数函数

6. 第三境界:purrr

学习purrr,可以放弃学习apply家族了,该有的都有,逻辑更清楚,学完之后就能用,完全没有出家的感觉。

备注: 这里是指从入门到出家的感觉

purrr包中的函数主要是map,有三类:

  • map函数,支持一元函数
  • map2函数,支持二元函数
  • pmap函数,支持多元函数

学习R语言念咒语:Fish,Fish,give me Fish

这里,我们用map做一个演示:

> library(purrr)
> map(dat,mean)
$y1
[1] 0.2194833

$y2
[1] 10.32957

用法和apply类似。将其转化为数据框:

> map_df(dat,mean)
# A tibble: 1 x 2
     y1    y2
  <dbl> <dbl>
1 0.219  10.3

用匿名函数试试:

> map_df(dat,~mean(.))
# A tibble: 1 x 2
     y1    y2
  <dbl> <dbl>
1 0.219  10.3

7. 用purrr演示一个复杂的例子

「批量建模」

用一个多年多点的数据,计算每个地点的方差分析,共有五个地点,用一行map函数全部搞定,是时候展示真正的实力了……

> library(learnasreml)
> data(MET)
> str(MET)
'data.frame':	400 obs. of  5 variables:
 $ Year    : Factor w/ 2 levels "2009","2010": 1 1 1 1 1 1 1 1 1 1 ...
 $ Location: Factor w/ 5 levels "CI","FL","KN",..: 3 3 3 3 3 3 3 3 3 3 ...
 $ Rep     : Factor w/ 4 levels "1","2","3","4": 1 1 1 1 1 1 1 1 1 1 ...
 $ Cul     : Factor w/ 10 levels "CalhounGray",..: 3 1 9 2 5 4 7 10 6 8 ...
 $ Yield   : num  56.2 74.2 32.6 74.2 64.8 ...

「代码:」

library(tidyverse)
MET %>% split(.$Location) %>% map(.,~aov(Yield ~ Cul,.) %>% summary)
  • MET为数据
  • split将Location进行分割,成为list的5个元素
  • map调用匿名函数进行方差分析
    • aov为方差分析,Yield ~ Cul为模型
  • summary为显示方差分析结果

「结果:」

> MET %>% split(.$Location) %>% map(.,~aov(Yield ~ Cul,.) %>% summary)
$CI
            Df Sum Sq Mean Sq F value  Pr(>F)   
Cul          9   8696   966.2   3.193 0.00277 **
Residuals   69  20879   302.6                   
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
1 observation deleted due to missingness

$FL
            Df Sum Sq Mean Sq F value Pr(>F)
Cul          9  10151  1127.9   1.565  0.143
Residuals   69  49723   720.6               
1 observation deleted due to missingness

$KN
            Df Sum Sq Mean Sq F value   Pr(>F)    
Cul          9   8236   915.1   4.038 0.000338 ***
Residuals   70  15863   226.6                     
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

$SC
            Df Sum Sq Mean Sq F value   Pr(>F)    
Cul          9  24478  2719.8     5.6 8.42e-06 ***
Residuals   70  33996   485.7                     
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

$TX
            Df Sum Sq Mean Sq F value Pr(>F)
Cul          9   5784   642.6   1.326   0.24
Residuals   69  33429   484.5               
1 observation deleted due to missingness

结果可以看到,每个地点都有一个方差分析表,每个元素为地点的方差分析结果。

8. 啥也别说,双击666吧

欢迎关注我的公众号:育种数据分析之放飞自我。主要分享R语言,Python,育种数据分析,生物统计,数量遗传学,混合线性模型,GWAS和GS相关的知识。




https://wap.sciencenet.cn/blog-2577109-1290630.html

上一篇:混合线性模型的可视化
下一篇:亲缘关系推断软件:king

0

该博文允许注册用户评论 请点击登录 评论 (0 个评论)

数据加载中...

Archiver|手机版|科学网 ( 京ICP备07017567号-12 )

GMT+8, 2021-7-26 13:26

Powered by ScienceNet.cn

Copyright © 2007- 中国科学报社

返回顶部