我有一个表,我试图根据另一列中的变量,通过一列中特定的均值子集进行标准化。理想情况下,我的代码会将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语句的情况下正确地将我的数据子集化以进行标准化。
答案 0 :(得分:1)
尝试以下方法:
reads <- merge(reads, coverage_summary)
reads <- mutate(reads, normalized = coverage_depth / mean)
基本上,这应该将您的汇总列加入到原始数据中,之后,创建规范化列应该是微不足道的。这也避免了必须创建一个自定义函数,该函数可以解释53种不同的值。