2016-03-16 31 views
1

比较两列替换值我有一个数据帧的样子:如何通过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") 

我想用字母“I”来代替较长的字符串列“RE”或“AL”而较短的一个用字母“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

一个基本的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 
+0

@Jaap:感谢你对你的矫正,但为什么删除你的答案?我看到2种索引策略是互补的。 –

+0

也许你是对的;没有删除我的答案 – Jaap

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 
0

在这里工作是一个简单的循环,完成工作:

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" 
    } 
} 
0

一个替代基础R溶液(compareble到@ 42-的答案,但与前 - 定义索引):

# create needed indexes 
idx1 <- !(nchar(df$RE) == 1 & nchar(df$AL) == 1) 
idx2 <- (nchar(df$RE) > nchar(df$AL)) + 1L 
idx3 <- (nchar(df$RE) < nchar(df$AL)) + 1L 

# replace the values 
df$RE[idx1] <- c('D','I')[idx2][idx1] 
df$AL[idx1] <- c('D','I')[idx3][idx1] 

这给:

> 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