给出以下数据框:
| feature | gene | target | pos |
| 1_1_1 | NRAS | AATTGG | 60 |
| 1_1_1 | NRAS | TTGGCC | 6 |
| 1_1_1 | NRAS | AATTGG | 20 |
| 1_1_1 | KRAS | GGGGTT | 0 |
| 1_1_1 | KRAS | GGGGTT | 0 |
| 1_1_1 | KRAS | GGGGTT | 0 |
| 1_1_2 | NRAS | CCTTAA | 2 |
| 1_1_2 | NRAS | GGAATT | 8 |
| 1_1_2 | NRAS | AATTGG | 60 |
对于每个功能,我想根据以下规则计算每个基因中出现多少个靶标:
matches.groupby(["FeatureID", "gene"]).size().reset_index()
matches['multi_mapped'] = np.where(matches.groupby(["FeatureID", "gene", "target"]).pos.transform('nunique') > 1, "T", '')
这给了我一个数据框,其中出现在多个位置的目标被标记为true。现在,我只需要弄清楚如何将计数标准化。
| feature | gene | count
| 1_1_1 | NRAS | 2
| 1_1_1 | KRAS | 1
| 1_1_2 | NRAS | 3
因此,在上面的示例中,对于1_1_1 NRAS,在位置60和位置20都找到了AATTGG,它们的计数均为0.5。由于TTGGCC在一个位置被发现一次,因此其计数为1。这使总数为2。
如果在同一位置3次发现1_1_1 NRAS TTGGCC,则每个都将计数为1,总计3 + .5 + .5 =4。
解决方案需要检查出现在不同位置的相同目标,然后相应地调整计数,这就是我遇到困难的部分。我的最终目标是选择每组中计数最高的基因。
答案 0 :(得分:0)
对我来说还不是很清楚,为什么第一行的计数应该为2。您能尝试解决这个问题吗?
import pandas as pd
feature = ["1_1_1"]*6 +["1_1_2"]*3
gene = ["NRAS"]*3+["KRAS"]*3+["NRAS"]*3
target = ["AATTGG","TTGGCC", "AATTGG"]+ ["GGGGTT"]*3 + ["CCTTAA", "GGGGTT", "AATTGG"]
pos = [60,6,20,0,0,0,2,8,60]
df = pd.DataFrame({"feature":feature,
"gene":gene,
"target":target,
"pos":pos})
df.groupby(["feature", "gene"])\
.apply(lambda x:len(x.drop_duplicates(["target", "pos"])))
答案 1 :(得分:0)
好的,我知道了。如果有一种更有效的方法可以做到这一点,那么我就不知所措!
# flag targets that are multi-mapped and add flag as new column
matches['multi_mapped'] = np.where(matches.groupby(["FeatureID", "gene", "target"]).pos.transform('nunique') > 1, "T", '')
# separate multi and non multi mapped reads using flag
non = matches[matches["multi_mapped"] != "T"]\
.drop("multi_mapped", axis=1)
multi = matches[matches["multi_mapped"] == "T"]\
.drop("multi_mapped", axis=1)
# add counts to non multi mapped reads
non = non.groupby(["FeatureID", "gene", "target"])\
.count().reset_index().rename(columns={"pos":"count"})
# add counts to multi-mapped reads with normaliztion
multi["count"] = multi.groupby(["FeatureID", "gene", "target"])\
.transform(lambda x: 1/x.count())
multi.drop("pos", axis=1, inplace=True)
# join the multi and non back together
counts = pd.concat([multi, non], axis=0)