【问题标题】:replace partial of character string in a data frame by conditions in r用r中的条件替换数据框中的部分字符串
【发布时间】:2016-01-05 19:08:58
【问题描述】:

我有一个这样的数据框:

df = read.table(text="REF   Alt S00001  S00002  S00003  S00004  S00005
 TAAGAAG    TAAG    TAAGAAG/TAAGAAG TAAGAAG/TAAG    TAAG/TAAG   TAAGAAG/TAAGAAG TAAGAAG/TAAGAAG
 T  TG  T/T -/- TG/TG   T/T T/T
 CAAAA  CAAA    CAAAA/CAAAA CAAAA/CAAA  CAAAA/CAAAA -/- CAAAA/CAAAA
 TTGT   TTGTGT  TTGT/TTGT   TTGT/TTGT   TTGT/TTGT   TTGTGT/TTGTGT   TTGT/TTGTGT
 GTTT   GTTTTT  GTTT/GTTTTT GTTT/GTTT   GTTT/GTTT   GTTT/GTTT   GTTTTT/GTTTTT", header=T, stringsAsFactors=F)

我想将由“/”分隔的字符元素替换为“D”或“I”,具体取决于“REF”和“Alt”列中字符串的长度。如果元素匹配最长的元素,它们将被“I”替换,否则被“D”替换。但是“-”没有变化。所以预期结果为:

REF Alt S00001  S00002  S00003  S00004  S00005
TAAGAAG TAAG    I/I I/D D/D I/I I/I
T   TG  D/D -/- I/I D/D D/D
CAAAA   CAAA    I/I I/D I/I -/- I/I
TTGT    TTGTGT  D/D D/D D/D I/I D/I
GTTT    GTTTTT  D/I D/D D/D D/D I/I

【问题讨论】:

    标签: regex r dna-sequence


    【解决方案1】:

    这是一种方法。我使用了 stringi 包,因为它可以很好地处理要搜索的模式向量和字符串向量。

    先确定哪个字符串短,哪个长:

    short <- ifelse(nchar(df$Alt) > nchar(df$REF), df$REF, df$Alt)
    long <- ifelse(nchar(df$REF) > nchar(df$Alt), df$REF, df$Alt)
    

    使用这些并遍历您的列,并根据需要分配替换。首先替换长模式以避免同时匹配短模式和长模式的字符串出现问题:

    library(stringi)
    
    df[,!(names(df) %in% c("REF", "Alt"))] <- # assign into original df
      lapply(1:(ncol(df) - 2), # - 2 because there are two columns we don't use
        function(ii) stri_replace_all_fixed(df[ ,ii + 2], long, "I")) # + 2 to skip first 2 columns
    
    df[,!(names(df) %in% c("REF", "Alt"))] <- 
      lapply(1:(ncol(df) - 2),
        function(ii) stri_replace_all_fixed(df[ ,ii + 2], short, "D"))
    
    #      REF    Alt S00001 S00002 S00003 S00004 S00005
    #1 TAAGAAG   TAAG    I/I    I/D    D/D    I/I    I/I
    #2       T     TG    D/D    -/-    I/I    D/D    D/D
    #3   CAAAA   CAAA    I/I    I/D    I/I    -/-    I/I
    #4    TTGT TTGTGT    D/D    D/D    D/D    I/I    D/I
    #5    GTTT GTTTTT    D/I    D/D    D/D    D/D    I/I
    

    【讨论】:

      【解决方案2】:

      您可以使用REFAlt 的所有组合以及ID 的相应组合创建一个地图:

      refalt <- data.frame(
          from=c(df$REF, df$Alt),
          to=c(rep('I', length(df$REF)), rep('D', length(df$Alt))),
          stringsAsFactors=FALSE)
      refalt <- rbind(refalt, c('-', '-'))
      from <- expand.grid(refalt$from, refalt$from)
      to <- expand.grid(refalt$to, refalt$to)
      map <- paste(to[,1], to[,2], sep='/')
      names(map) <- paste(from[,1], from[,2], sep='/')
      

      然后,您可以为每一列使用地图:

      for (name in paste0('S0000', seq(5))) {
          df[[name]] <- map[df[[name]]]
      }
      

      【讨论】:

        猜你喜欢
        • 2011-07-26
        • 2018-08-01
        • 2021-10-19
        • 2012-12-30
        • 2017-07-08
        • 1970-01-01
        • 1970-01-01
        • 2021-10-20
        • 1970-01-01
        相关资源
        最近更新 更多