所有,我有一个大的基因组数据,我想做查找和替换基于"REF"one_answers";ALT"每行的列值。替换规则为:
- 如果值= 0,则用"-/-">
- 如果值= 1,则用两个REF等位基因代替
- 如果值= 2,则替换为两个ALT等位基因
- 如果值= 3,则替换为一个REF等位基因和一个ALT等位基因
下面是一个示例数据的小子集:
Chr Pos REF ALT A B C D E
1 70 A G 1 0 1 1 1
1 80 T G 1 0 3 3 3
1 100 C T 1 0 1 1 1
2 20 G A 1 0 0 0 1
2 80 C T 1 0 0 0 2
期望的输出是:
Chr Pos REF ALT A B C D E
1 70 A G A/A -/- A/A A/A A/A
1 80 T G T/T -/- T/G T/G T/G
1 100 C T C/C -/- C/C C/C C/C
2 20 G A G/G -/- -/- -/- G/G
2 80 C T C/C -/- -/- -/- T/T
可复制数据帧:
df=data.frame(
Chr=c(1,1,1,2,2),
Pos=c(70,80,100,20,80),
REF=c("A","T","C","G","C"),
ALT=c("G","G","T","A","T"),
A=c(1,1,1,1,1),
B=c(0,0,0,0,0),
C=c(1,3,1,0,0),
D=c(1,3,1,0,0),
E=c(1,3,1,1,2)
)
我为任务写了一个for循环:
K=data.frame()
for (r in 1:nrow(df)){
k=df[r,]
ks=df[r,-1:-4]
ks[ks==0]="-/-"
ks[ks==1]=paste0(k$REF,"/",k$REF)
ks[ks==2]=paste0(k$ALT,"/",k$ALT)
ks[ks==3]=paste0(k$REF,"/",k$ALT)
ks=cbind(k[,1:4],ks)
K=rbind(K,ks)
}
那工作得很好,然而,我有大约15万行,逐行操作需要很长时间,所以我想知道是否有一个更快的方法来处理这个?
非常感谢你的帮助!
我们可以使用case_when
-循环across
列'A'到'E',根据' case_when
sprintf
创建格式library(dplyr)
df %>%
mutate(across(A:E, ~ case_when(. == 0 ~ '-/-',
. == 1 ~ sprintf('%1$s/%1$s', REF),
.==2 ~ sprintf('%1$s/%1$s', ALT),
TRUE ~ sprintf('%s/%s', REF, ALT))))
与产出
Chr Pos REF ALT A B C D E
1 1 70 A G A/A -/- A/A A/A A/A
2 1 80 T G T/T -/- T/G T/G T/G
3 1 100 C T C/C -/- C/C C/C C/C
4 2 20 G A G/G -/- -/- -/- G/G
5 2 80 C T C/C -/- -/- -/- T/T
注意:由于这是按列而不是按行完成的,因此它应该比OP的方法快得多