分组计算描述性统计量函数—by()函数

论坛 期权论坛 期权     
生信技能树   2019-6-7 07:06   3768   0
《R语言实战》这本书上是这样描述
  1. by()
复制代码
函数的:
使用by()分组计算描述性统计量,它可以一次返回若干个统计量。格式为:by(data, INDICES, FUN)其中data是一个数据框或矩阵;INDICES是一个因子或因子组成的列表,定义了分组;FUN是任意函数。
简单点说
  1. by(data, INDICES, FUN)
复制代码
函数的典型用法: 是将
  1. data
复制代码
数据框或矩阵按照
  1. INDICES
复制代码
因子水平进行分组,然后对每组应用
  1. FUN
复制代码
函数。是不是没懂?反正看完后我没懂~
下面我们通过实例来理解下
  1. by()
复制代码
函数:比如2019年第二季度Jimmy老师收了五个学徒:
  • 他们姓名分别是:
    1. xg;xj;hj;wh;xs
    复制代码

  • 他们年纪分别是:
    1. 23;24;25;26;27
    复制代码

  • 他们的性别分别是:
    1. male;female;female;male;female
    复制代码

将以上学徒信息构建成数据框,存到
  1. biotrainee
复制代码
变量名中:
  1. biotrainee  biotrainee  #看下数据框内容  name ages gender1   xg   23   male2   xj   24 female3   hj   25 female4   wh   26   male5   xs   27 female
复制代码
学徒名字年龄信息纯属虚构,如有雷同纯属巧合
我们想要将所有学徒按照性别分组,并分别计算每组学徒年龄的平均值,就可以通过
  1. by()
复制代码
函数来实现,我们体会一下:
  1. by(biotrainee,biotrainee$gender,function(x) mean(x[,2]))
复制代码
  1. > by(biotrainee,biotrainee$gender,function(x) mean(x[,3]))biotrainee$gender: female[1] 25.33333----------------------------------------------------------------------------- biotrainee$gender: male[1] 24.5
复制代码
  1. by
复制代码
做了什么?将第一个参数(学徒信息)按照第二个参数(性别)进行分组,然后每组应用第三个参数所定义的函数(求每组第三列即年龄的平均值)。还没懂?没关系,来个示意图:
熟悉
  1. split()
复制代码
函数的可以看出,按照
  1. gender
复制代码
列分组那步,
  1. split()
复制代码
函数可以到达同样的效果:
  1. split(biotrainee,biotrainee$gender)
复制代码
  1. > split(biotrainee,biotrainee$gender)$`female`  name gender ages2   xj female   243   hj female   255   xs female   27$male  name gender ages1   xg   male   234   wh   male   26
复制代码
  1. split()
复制代码
函数分好组之后,我们再用
  1. lapply
复制代码
就可以看到:
  1. > lapply(split(biotrainee,biotrainee$gender),function(x) mean(x[,3]))$`female`[1] 25.33333$male[1] 24.5
复制代码
  1. lapply()
复制代码
中的 “l” 代表list,它接受
  1. list
复制代码
作为输入,并将指定的操作应用于列表中的所有元素。在list上逐个元素调用FUN函数。可以用于
  1. data.frame
复制代码
上,因为
  1. data.frame
复制代码
是一种特殊形式的
  1. list
复制代码

到这里
  1. by()
复制代码
函数的用法就讲完了,只讲基本用法,不讲在实际数据分析过程中能解决什么问题?还是那句话,不是我的风格~
这几天我在看Jimmy老师在B站上的GEO数据挖掘视频课程,课程里介绍到GEO数据挖掘分析流程:看文章找GSE编号 --> 到GEO数据库搜索下载数据 --> 提取表达矩阵exp --> id转换….在id转换过程中,经过一系列处理我们得到了ids,它与我们提取的表达矩阵exp的探针顺序一一对应:
  1. > head(ids)  probe_id    symbol1  7896759 LINC011282  7896761    SAMD113  7896779    KLHL174  7896798   PLEKHN15  7896817     ISG156  7896822      AGRN> head(exp)        GSM1052615 GSM1052616 GSM1052617 GSM1052618 GSM1052619 GSM10526207896759    8.75126    8.61650    8.81149    8.32067    8.41445    8.452087896761    8.39069    8.52617    8.43338    9.17284    9.10216    9.141207896779    8.20228    8.30886    8.18518    8.13322    8.06453    8.158847896798    8.41004    8.37679    8.27521    8.34524    8.35557    8.444097896817    7.72204    7.74572    7.78022    7.72308    7.53797    7.734017896822    9.19237    9.10929    9.03668    9.94821    9.96994    9.99839
复制代码
这时,我们就可以对表达矩阵exp进行分组,将同一个
  1. symbol
复制代码
所对应的多个探针分成不同的组,并对每组探针进行统计:计算每组中每行探针表达量的平均值(也就是每个探针在6个样本中表达量的均值rowMeans(x)),再取平均值最大的那个探针作为该symbol所对应的唯一探针,我们上面讲的
  1. by()
复制代码
函数就可以完成以上操作:
  1. tmp = by(exp,         ids$symbol,         function(x) rownames(x)[which.max(rowMeans(x))])probes = as.character(tmp)
复制代码
第二个参数
  1. ids$symbol
复制代码
定义了分组,将第一参数—exp表达矩阵分成了若干个小矩阵,每个小矩阵里存放着同一个symbol所对应的所有探针。第三个参数是我们自己定义的函数:计算每个小矩阵中每行探针表达量的平均值(也就是每个探针在6个样本中表达量的均值
  1. rowMeans(x)
复制代码
),再取平均值最大的那个探针作为该symbol所对应的唯一探针
  1. which.max(rowMeans(x))
复制代码
  1. by()
复制代码
函数就可以返回每个分组里的统计结果,即每个symbol所对应的唯一探针ID
  1. probe_id
复制代码
,存放在tmp里。用
  1. probes = as.character(tmp)
复制代码
将结果变为纯字符型向量:
  1. > head(tmp)INDICES     A1CF       A2M     A2ML1   A3GALT2    A4GALT     A4GNT "7933640" "7960947" "7953775" "7914643" "8076497" "8090955" > head(probes)[1] "7933640" "7960947" "7953775" "7914643" "8076497" "8090955">
复制代码
免费的课程和学习资源 :
分享到 :
0 人收藏
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

积分:
帖子:
精华:
期权论坛 期权论坛
发布
内容

下载期权论坛手机APP