基于 R 中的子集均值对数据进行归一化

Normalizing data based on Subset Mean in R

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

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

我的 table 看起来像这样:

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

首先我加载我的 table:

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

然后我调用 plyr 来计算 chr 和 strains 列的所有组合的 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 语句的情况下正确地对我的数据进行子集化以进行规范化。

尝试以下操作:

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

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