「答果子问」R语言如何提取特定的字符串

作者: xuzhougeng | 来源:发表于2018-12-11 18:06 被阅读90次

    R语言如何提取特定的字符串

    这个帖子是为了果子的一个提问

    R语言能不能实现匹配括号里面的内容, 但是不包括括号

    这个问题来自于他的一篇帖子有些GEO平台的探针转换比较麻烦, 里面提取字符串的代码不够简洁。

    果子在原帖里面引用我的一句话,"正则表达式是我们认识这个世界的哲学".既然我说了这句话,那么我就得贯彻我的哲学理念,在R里面用正则表达式把数据给提取了。

    首先在https://www.ncbi.nlm.nih.gov/geo/query/acc.cgi?acc=GPL4381把对应的数据给下载了

    数据下载

    然后用data.tablefread进行高效智能的读取数据

    GPL4381 <- data.table::fread("GPL4381-4306.txt")
    

    正则表达式的核心在于观察数据,提取模式,这也就是我说"正则表达式是我们认识这个世界的哲学"的原因,因为我们就是通过不断观察世界研究规律指导生活。

    观察模式

    从上图中你发现了什么,是不是都是"xxxx(基因名),xxx"这种情况。

    于是我们就可以通过R语言的regexpr提取上面基因名的位置信息了

    pattern <- ".*\\((?<ID>[A-Za-z0-9]*)\\),.*"
    result <- regexpr(pattern= pattern, text = GPL4381$GB_DEFINITION, perl=TRUE)
    

    仔细观察下我的写的模式识别,pattern <- ".*\\((?<ID>[A-Za-z0-9]*)\\),.*", 你会发现我用到一个你未必见过的模式,(?<>),这是Perl 的正则表示系统里的模式,所以必须用perl=TRUE才能被R解读。它的作用就是把括号里面的模式单独分组。

    regexpr会返回匹配的内容的起始位置,匹配长度。如果匹配, 位置为"-1"

    start <- attr(result,"capture.start")
    length <- attr(result,"capture.length")
    name <- attr(result,"capture.name")
    

    之后,我们可以用substr根据位置信息进行提取。

    geneID <- ifelse(start > 0, 
                     substr(GPL4381$GB_DEFINITION, start[,name],start[,name] + length[,name]-1),NA)
    
    

    最终你查看geneID的前10个的时候,你会发现就是你想要的

    head(geneID,n=10)
    
    前十个

    当然如果你用stringr, 那代码其实更加简洁一些

    res <- stringr::str_match(string = GPL4381$GB_DEFINITION, pattern = pattern)
    geneID <- res[,2]
    head(geneID)
    
    前10个

    说下核心知识点:

    • regexpr可以返回匹配的起始位置和匹配长度,返回-1表示没有匹配
    • (?<组名>匹配模式): 对匹配内容进行分组, 在perl=TRUE下使用。

    相关文章

      网友评论

        本文标题:「答果子问」R语言如何提取特定的字符串

        本文链接:https://www.haomeiwen.com/subject/tspehqtx.html