根据R

时间:2016-08-09 23:33:00

标签: r subset plyr mean

我有一个表,我试图根据另一列中的变量,通过一列中特定的均值子集进行标准化。理想情况下,我的代码会将coverage_depth列中的所有数据除以特定应变变量(如2987)的平均值(同一列的子集的平均值)(chr列中仅SAG1的覆盖深度仅适用于2987中的应变柱)

我已经找到了很长的路要走这条路,但我真的希望有人有办法让它成为一个循环,这样我就不必在计算后手动输入方法。

我的表格如下:

B1  1073    320 2987
B1  1074    324 2987
B1  1075    330 2987
SAG1    955 31  2987
SAG1    956 30  2987
SAG1    957 29  2987
SAG1    958 29  2987
BTub    446 57  2987
BTub    452 59  2987
B1  1707    53  GRE_MIG
B1  1708    56  GRE_MIG
18S 1099    242 GRE_MIG
18S 1100    242 GRE_MIG
SAG1    888 7   GRE_MIG
SAG1    889 7   GRE_MIG
SAG1    890 7   GRE_MIG

首先我加载到我的表中:

reads<-read.table("3133_all.CNV.txt", sep = "\t", header = F)
colnames(reads)<-c("chr", "position", "coverage_depth", "strains"

然后我调用plyr来计算chr和菌株列的所有组合的coverage_depth的平均值

library(plyr)
    coverage_summary<-ddply(reads, c("chr", "strains"), summarise, mean = mean(coverage_depth))
    write.csv(format(coverage_summary, scientific=FALSE), file = "CNV_mean_07.27.16.csv", row.names = F)

这给了我更长的版本:

     chr    strains         mean
1    18S       2987 2.052802e+03
20   18S    GRE_MIG 2.674536e+01
126   B1    GRE_MIG 6.503342e+01
213 SAG1       2987 3.422057e+01
232 SAG1    GRE_MIG 5.863501e+00

我想出了如何通过我在chr SAG1从该菌株得到的平均值来归一化菌株的所有coverage_depth,我手动输入:

NormalizeSAG1<-function(coverage_depth, strains){ 
  if (strains %in% c("2987")) {
    coverage_depth<-coverage_depth/3.42
  } else if (strains %in% c("GRE_MIG")) {
    coverage_depth<-coverage_depth/5.86    
  } else { coverage.norm<-coverage_depth
  }}
reads$SAG1_normalized<-mapply(NormalizeSAG1, reads$coverage_depth, reads$strains)

问题是我有53种不同的菌株,我想根据chr栏中各自SAG1的平均值进行标准化。似乎for循环可能会这样做,但我无法弄清楚如何在没有大量ifelse语句的情况下正确地将我的数据子集化以进行标准化。

1 个答案:

答案 0 :(得分:1)

尝试以下方法:

reads <- merge(reads, coverage_summary)
reads <- mutate(reads, normalized = coverage_depth / mean)

基本上,这应该将您的汇总列加入到原始数据中,之后,创建规范化列应该是微不足道的。这也避免了必须创建一个自定义函数,该函数可以解释53种不同的值。