查找并按行替换r中大数据帧的条件列值

  • 本文关键字:数据帧 条件 替换 查找 r
  • 更新时间 :
  • 英文 :


所有,我有一个大的基因组数据,我想做查找和替换基于"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的方法快得多

最新更新