如何通过比较r中的两列来替换值

时间:2016-03-16 16:11:35

标签: r

我有一个数据框如下:

df<-read.table(text="ID           RE          AL 
140343         TC           T
200012      A       G
457096        GAA        GAAA
555084         AG           A
557151          T         TAA
752311   GAATTAAT        GAAT
810001     ATTTTT       ATTTT
880420 GAAAAAAAAA GAAAAAAAAAA", header=TRUE, colClasses="character")

我想将字母“RE”或“AL”中的较长字符串替换为字母“I”,将较短的字符串替换为字母“D”。如果两列都有一个字母,则没有变化。

预期结果:

ID      RE  AL
140343  I   D
200012  A   G
457096  D   I
555084  I   D
557151  D   I
752311  I   D
810001  I   D
880420  D   I

我尝试了我的脚本:

max <- apply(df[2:3], 1, function(x) max(nchar(x)))
index <- max > 1
if(nchar(df$RE[index])==max[index]){
  df$RE[index] <- "I"
  df$AL[index] <- "D"
}else{
  df$RE[index] <- "D"
  df$AL[index] <- "I"
}

4 个答案:

答案 0 :(得分:4)

碱基R向量化溶液。第一行定义要处理的行的子集。然后两条具有相反方向的线进行比较,您可以根据比较选择“D”或“I”:

noneq <- with( df, (nchar(RE) != 1)|( nchar(AL) != 1) )
df[ noneq, "RE"] <- with(df[ noneq, ], c("D","I")[1+(nchar(RE) > nchar(AL) )])
df[ noneq, "AL"] <- with(df[ noneq, ], c("D","I")[1+(RE=="D" )])  # opposite of RE

df
#==============
      ID RE AL
1 140343  I  D
2 200012  A  G
3 457096  D  I
4 555084  I  D
5 557151  D  I
6 752311  I  D
7 810001  I  D
8 880420  D  I

答案 1 :(得分:2)

这是一个可能适合您的dplyr解决方案

library(dplyr)

df %>%
    mutate(RE = ifelse(nchar(RE) != 1 | nchar(AL) != 1,
                       ifelse(nchar(RE) > nchar(AL), 'I', 'D'), RE),
           AL = ifelse(RE=='I', 'D', ifelse(RE=='D', 'I', AL)))

##       ID RE AL
## 1 140343  I  D
## 2 200012  A  G
## 3 457096  D  I
## 4 555084  I  D
## 5 557151  D  I
## 6 752311  I  D
## 7 810001  I  D
## 8 880420  D  I

答案 2 :(得分:0)

这是一个简单的for循环,可以完成工作:

for (i in seq(1:nrow(df))){
    if(nchar(df[i, 3]) - nchar(df[i, 2]) < 0){
        df[i, 3] <- "D"
        df[i, 2] <- "I"
    }else if(nchar(df[i, 3]) - nchar(df[i, 2]) > 0){
        df[i, 3] <- "I"
        df[i, 2] <- "D"
    }
}

答案 3 :(得分:0)

另一种基本R解决方案(与@ 42-答案相比,但预先定义了索引):

> df
      ID RE AL
1 140343  I  D
2 200012  A  G
3 457096  D  I
4 555084  I  D
5 557151  D  I
6 752311  I  D
7 810001  I  D
8 880420  D  I

给出:

{{1}}