R提取字符串的一部分

20
我有一个提取字符串部分的问题。比如说我有一个像这样的字符串:
a <- "DP=26;AN=2;DB=1;AC=1;MQ=56;MZ=0;ST=5:10,7:2;CQ=SYNONYMOUS_CODING;GN=NOC2L;PA=1^1:0.720&2^1:0"

我需要提取在GN=;之间的所有内容,因此这里将是NOC2L

这是否可能?

注意:这是VCF文件格式中的INFO列。 GN是基因名称,因此我们要从INFO列中提取基因名。


问题有点不清楚,因为似乎您想要的字符串并不总是跟着分号。 - jbaums
6个回答

36

试一下这个:

sub(".*?GN=(.*?);.*", "\\1", a)
# [1] "NOC2L"

1
感谢Kohske。如果NOC2L在行末呢?那么整行都会被选中! - Lisann
你的字符串是什么样子的?能否提供一个例子? - kohske
a <- "DP=26;AN=2;DB=1;AC=1;MQ=56;MZ=0;ST=5:10,7:2;CQ=SYNONYMOUS_CODING;GN=NOC2L" - Lisann
1
尝试这个:sub(".*?GN=(.*?)(;.*|$)", "\\1", a) - kohske
谢谢你的问题/答案。如果在“a”中没有这样的东西,那该怎么办?在这种情况下,我希望它返回NA。但是它现在不是这种形式。有什么想法吗? - Rotail

15

假设分号分隔您的元素,并且等号仅出现在键/值对之间,那么一种非严格正则表达式方法是:

bits <- unlist(strsplit(a, ';'))
do.call(rbind, strsplit(bits, '='))

      [,1] [,2]               
 [1,] "DP" "26"               
 [2,] "AN" "2"                
 [3,] "DB" "1"                
 [4,] "AC" "1"                
 [5,] "MQ" "56"               
 [6,] "MZ" "0"                
 [7,] "ST" "5:10,7:2"         
 [8,] "CQ" "SYNONYMOUS_CODING"
 [9,] "GN" "NOC2L"            
[10,] "PA" "1^1:0.720&2^1:0"  

那就只是选择适当的元素的问题。


3
a <- "DP=26;AN=2;DB=1;AC=1;MQ=56;MZ=0;ST=5:10,7:2;CQ=SYNONYMOUS_CODING;GN=NOC2L;PA=1^1:0.720&2^1:0"
m = regexpr("GN.*;",a)
substr(a,m+3,m+attr(m,"match.length")-2)

3
一种方法是:
gsub(".+=(\\w+);.+", "\\1", a, perl=T)

我相信有更优雅的方法来解决这个问题。


2

由于字符串来自VCF文件,因此我们可以使用VariantAnnotation软件包:

library(VariantAnnotation)

# read dummy VCF file
fl <- system.file("extdata", "chr22.vcf.gz", package="VariantAnnotation")
vcf <- readVcf(fl, "hg19")

# see first 5 variables for info column
info(vcf)[1:3, 1:5]
# DataFrame with 3 rows and 5 columns
#                  LDAF   AVGPOST       RSQ     ERATE     THETA
#             <numeric> <numeric> <numeric> <numeric> <numeric>
# rs7410291      0.3431    0.9890    0.9856     2e-03    0.0005
# rs147922003    0.0091    0.9963    0.8398     5e-04    0.0011
# rs114143073    0.0098    0.9891    0.5919     7e-04    0.0008

# Now extract one column, e.g.: LDAF
info(vcf)[1:3, "LDAF"]
# [1] 0.3431 0.0091 0.0098

在上面的VCF对象中没有“GN”列,但是思路是相同的,因此在您的情况下,以下应该有效:
# extract gene name
info(vcf)[, "GN"]

1
作为将反向引用与sub结合的替代方案,您可以使用前后查找断言以及抽取操作,如下所示:
library(stringr)
a <- "DP=26;AN=2;DB=1;AC=1;MQ=56;MZ=0;ST=5:10,7:2;CQ=SYNONYMOUS_CODING;GN=NOC2L;PA=1^1:0.720&2^1:0"
str_extract(a, "(?<=GN=)[^;]*(?=;|$)")
# [1] NOC2L

在哪里:

  • (?<=GN=) 断言 GN= 必须在匹配项之前
  • (?=;|$) 断言 ; 或字符串结尾 ($) 必须在匹配项之后
  • [^;]* 匹配任意数量的非 ; 字符

注意:使用 [^;]* 而不是 .*,因为后者可能会匹配一个 ; 并继续匹配直到字符串结尾 ($)。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接