2016-03-16 76 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