如何使用小写敏感度作为因素和后视功能在 R 中拆分列

How to split a column in R using lower case sensitivity as a factor and look-behind feature

我在 R 中有一个大型数据框,它由单个列中的小写字母和大写字母组成。

df1 <- data.frame(a = c('GCCTTGATTTTTTGGCGGGGACCGTcatGGCGTCGC', 'GATTTTTTGGCGGGGACCGTcatGGCGTCGC', 'TCACCACCATCtCATTCTGC', 'ACTGGTTCCAcCAGCGGGTCACGAC'), 
                  stringsAsFactors = FALSE)

我希望输出将所有 'upper case letters' 放在任何小写字母的左侧;即类似于后视功能的东西。

例如

GCCTTGATTTTTTGGCGGGGACCGTcatGGCGTCGC 将变为 GCCTTGATTTTTTGGCGGGGACCGT GATTTTTTGGCGGGGACCGTcatGGCGTCGC 将变成 GATTTTTTGGCGGGGACCGT ACTGGTTCAcCAGCGGGTCACGAC 将变为 ACTGGTTCCA

我只对第一个小写字符左侧的大写字符感兴趣。如果没有小写实例,我也希望代码不会失败。

我试过看: 但我似乎无法调整它以查找大写字母。

非常感谢您的帮助。

sub("([A-Z]+)[a-z].*", "\1", df1$a)

# [1] "GCCTTGATTTTTTGGCGGGGACCGTatGGCGTCGC"
# [2] "GATTTTTTGGCGGGGACCGTatGGCGTCGC"     
# [3] "TCACCACCATCCATTCTGC"                
# [4] "ACTGGTTCCACAGCGGGTCACGAC"

代码:

library(tidyverse)

df1 <- data.frame(a = c('GCCTTGATTTTTTGGCGGGGACCGTcatGGCGTCGC', 'GATTTTTTGGCGGGGACCGTcatGGCGTCGC', 'TCACCACCATCtCATTCTGC', 'ACTGGTTCCAcCAGCGGGTCACGAC', 'BAARA'), 
                  stringsAsFactors = FALSE)
df1


df1$a <- str_trim(str_extract(df1$a , "([:upper:]|[:space:]){2,}"))
df1

输出:

                          a
1 GCCTTGATTTTTTGGCGGGGACCGT
2      GATTTTTTGGCGGGGACCGT
3               TCACCACCATC
4                ACTGGTTCCA
5                     BAARA    #This one not having any lower case charater from the begining

输入 NA,其中字符串没有任何小写字符。

 for (i in 1 :nrow(df1)){  
    if(is.na(str_extract(df1[i,'a'], "([:lower:]|[:space:]){1,}"))) 
       {df1[i,'a'] <- NA}
    else 
       {df1[i,'a'] <- str_trim(str_extract(df1[i,'a'] , "([:upper:]|[:space:]){2,}"))}
     df1[i,'b'] <- df1[i,'a']   
    }
 df1

输出:

                          a
1 GCCTTGATTTTTTGGCGGGGACCGT
2      GATTTTTTGGCGGGGACCGT
3               TCACCACCATC
4                ACTGGTTCCA
5                      <NA>

您可以使用 sub[a-z].*[[:lower:]].* 来删除第一个小写字母和后面的所有内容。

sub("[a-z].*", "", df1$a)
#sub("[[:lower:]].*", "", df1$a) #Alternative
#[1] "GCCTTGATTTTTTGGCGGGGACCGT" "GATTTTTTGGCGGGGACCGT"     
#[3] "TCACCACCATC"               "ACTGGTTCCA"               

设置为NA,其中没有小写:

df1 <- rbind(df1, "ABC")               #Add without lower case
is.na(df1$a) <- !grepl("[a-z]", df1$a) #set NA where no lower case
sub("[a-z].*", "", df1$a)
#[1] "GCCTTGATTTTTTGGCGGGGACCGT" "GATTTTTTGGCGGGGACCGT"     
#[3] "TCACCACCATC"               "ACTGGTTCCA"               
#[5] NA                         

您可以使用带有正前瞻正则表达式的一行代码(捕获第一个小写字母之前的所有内容)来完成所有操作,因此您无需处理 NA。要么匹配要么不匹配

stringr::str_extract(df1$a, ".+?(?=[a-z])")

#[1] "GCCTTGATTTTTTGGCGGGGACCGT" "GATTTTTTGGCGGGGACCGT"      "TCACCACCATC"              
#[4] "ACTGGTTCCA"                NA    

添加一个新列 b,结果如评论中所问:

df1 |> dplyr::mutate(b = stringr::str_extract(a, ".+?(?=[a-z])"))

#                                      a                         b
# 1 GCCTTGATTTTTTGGCGGGGACCGTcatGGCGTCGC GCCTTGATTTTTTGGCGGGGACCGT
# 2      GATTTTTTGGCGGGGACCGTcatGGCGTCGC      GATTTTTTGGCGGGGACCGT
# 3                 TCACCACCATCtCATTCTGC               TCACCACCATC
# 4            ACTGGTTCCAcCAGCGGGTCACGAC                ACTGGTTCCA
# 5                                BAARA                      <NA>