R. 根据具有不同级别的其他 2 列的值重新编码列

R. Recode columns based on values of other 2 columns that have different levels

我有一个包含 10000 行和 1000 列的数据框,如下所示:

ID    a0    a1    V1    V2    V3
rs1   G     A     0     0     1
rs2   C     T     1     0     0
rs3   T     C     0     1     1    

a0和a1可以是A、T、C或G,并表示其他列是0还是1。比如第二行a0=G,a1=A,所以V1=0( G)、V2 = 0 (G) 和 V3 = 1 (A)。我期待这样的输出数据框:

ID    a0    a1    V1    V2    V3
rs1   G     A     G     G     A
rs2   C     T     T     C     C
rs3   T     C     T     C     C

非常感谢

我们可以使用lapplyifelse来进行替换。

dat[, -(1:3)] <- lapply(dat[, -(1:3)], function(x){
  x <- ifelse(x == 0, dat[, 2], dat[, 3])
  return(x)
})

dat
#    ID a0 a1 V1 V2 V3
# 1 rs1  G  A  G  G  A
# 2 rs2  C  T  T  C  C
# 3 rs3  T  C  T  C  C

数据

dat <- read.table(text = "ID    a0    a1    V1    V2    V3
rs1   G     A     0     0     1
rs2   C     T     1     0     0
rs3   T     C     0     1     1",
                  header = TRUE, stringsAsFactors = FALSE)

这是一个使用 dplyr

中的 case_when 的选项
library(dplyr)
df1 %>%
   mutate_at(vars(matches("^V\d+")), funs(case_when(!. ~ df1$a0, TRUE ~ df1$a1)))
#   ID a0 a1 V1 V2 V3
#1 rs1  G  A  G  G  A
#2 rs2  C  T  T  C  C
#3 rs3  T  C  T  C  C

矩阵索引来拯救,在设置 targetsource 变量后:

tgt <- c("V1","V2","V3")
src <- c("a0","a1")
dat[tgt] <- dat[src][cbind(seq_len(nrow(dat)), unlist(dat[tgt]+1))]

#   ID a0 a1 V1 V2 V3
#1 rs1  G  A  G  G  A
#2 rs2  C  T  T  C  C
#3 rs3  T  C  T  C  C