簡體   English   中英

如何通過比較R中的兩列來替換值

[英]how to replace values by comparing two columns in 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"
}

基本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

這是一個可能適合您的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

這是完成工作的簡單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"
    }
}

替代的基礎R解決方案(與@ 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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM