R 拆分字符列并获取字符串中字段的名称

R 拆分字符列并获取字符串中字段的名称,r,data.table,reshape,R,Data.table,Reshape,我需要将包含信息的列拆分为几列。 我会使用tstrsplit,但是相同类型的信息在行中的顺序不同,我需要提取变量中新列的名称。重要的是要知道:可能有很多信息(字段将成为新变量),但我不知道它们的全部,所以我不想要“一个字段一个字段”的解决方案 下面是我所拥有的一个例子: library(data.table) myDT <- structure(list(chr = c("chr1", "chr2", "chr4"), pos = c(123L, 43

我需要将包含信息的列拆分为几列。
我会使用
tstrsplit
,但是相同类型的信息在行中的顺序不同,我需要提取变量中新列的名称。重要的是要知道:可能有很多信息(字段将成为新变量),但我不知道它们的全部,所以我不想要“一个字段一个字段”的解决方案

下面是我所拥有的一个例子:

library(data.table)

myDT <- structure(list(chr = c("chr1", "chr2", "chr4"), pos = c(123L,
                  435L, 120L), info = c("type=3;end=4", "end=6", "end=5;pos=TRUE;type=2"
                  )), class = c("data.table", "data.frame"), row.names = c(NA,-3L))

#    chr pos                  info
#1: chr1 123          type=3;end=4
#2: chr2 435                 end=6
#3: chr4 120 end=5;pos=TRUE;type=2
库(data.table)

myDT目前,我通过以下代码获得了我想要的:

newDT <- reshape(splitstackshape::cSplit(myDT, "info", sep=";", "long")[, 
                  c(.SD, tstrsplit(info, "="))], 
                 idvar=c("chr", "pos"), direction="wide", timevar="V4", drop="info")
setnames(newDT, sub("V5\\.", "", names(newDT)))

newDT
#    chr pos type end  pos
#1: chr1 123    3   4 <NA>
#2: chr2 435 <NA>   6 <NA>
#3: chr4 120    2   5 TRUE
。用
cSplit
/
trstrplit
dcast
代替
重塑

cSplit(myDT, "info", ";", "long")[, c("t1", "t2") := tstrsplit(info, "=", fixed = TRUE)][, dcast(.SD, chr + pos ~ t1, value.var = "t2")]
myDT$type <- sub("^.*\\btype=([^;]+)\\b.*$", "\\1", myDT$info)
我们可以在
“;”
上拆分,然后将宽的形状改为长的形状,然后在
“=”
上再次拆分,然后将长的形状改为宽的形状:

dcast(
  melt(dt[,  paste0("col", 1:3) := tstrsplit(info, split = ";") ],
       id.vars = c("chr", "pos", "info"))[, -c("info", "variable")][
         ,c("x1", "x2") := tstrsplit(value, split = "=")][
           ,value := NULL][ !is.na(x1), ],
  chr + pos ~ x1, value.var = "x2")

#     chr pos end  pos type
# 1: chr1 123   4 <NA>    3
# 2: chr2 435   6 <NA> <NA>
# 3: chr4 120   5 TRUE    2

您可以对每个所需的提取字段分别调用
sub
,例如,对于
类型

cSplit(myDT, "info", ";", "long")[, c("t1", "t2") := tstrsplit(info, "=", fixed = TRUE)][, dcast(.SD, chr + pos ~ t1, value.var = "t2")]
myDT$type <- sub("^.*\\btype=([^;]+)\\b.*$", "\\1", myDT$info)
myDT$type以下是我的做法:

库(data.table)
第三个多年电价确定期:chr4 120 2 5正确

由(v0.3.0)

使用
regex
stringi
软件包于2019-11-29创建:

setDT(myDT) # After creating data.table from structure()

library(stringi)

fields <- unique(unlist(stri_extract_all(regex = "[a-z]+(?==)", myDT$info)))
patterns <- sprintf("(?<=%s=)[^;]+", fields)
myDT[, (fields) := lapply(patterns, function(x) stri_extract(regex = x, info))]
myDT[, !"info"]

    chr  pos type end
1: chr1 <NA>    3   4
2: chr2 <NA> <NA>   6
3: chr4 TRUE    2   5

我猜您的数据来自一个,如果是的话,有专门的工具来解决这些问题-

让我们创建用于测试的示例VCF文件:

# subset some data from 1000genomes data
tabix -h ftp://ftp-trace.ncbi.nih.gov/1000genomes/ftp/release/20100804/ALL.2of4intersection.20100804.genotypes.vcf.gz 17:1471000-1472000 > myFile.vcf
# zip it and index:
bgzip -c myFile.vcf > myFile.vcf.gz
tabix -p vcf myFile.vcf.gz
现在我们可以使用bcftools了。这里作为一个示例,我们从INFO列中对AF和DP进行子集设置:


有关更多选项,请参阅手册。

我不知道将出现的所有文件,它们可能很多,因此这不是一个足够公平的选项;当我发布这个答案时,我不知道这一点。我会添加它(顺便说一句,你没有给出想要的输出,你的答案遗漏了一些行…)我不需要将“;”改为“,”并且不喜欢
eval(解析(text=…))
。。。尽管如此,还是要感谢你的回答。我不能与个人品味争论,但是
parse
有一个不好的名声,因为它经常被用于错误的原因。下面就是它的适当用例,从一个字符串到另一个代码。您已经格式化了文本,但没有为R格式化,并且已经命名了列表,因此我的第一行将“a;b”更改为“list(a,b)”,从而使其成为R列表的代码。然后我们对它进行评估,并用它制作一个表。我得到一个很长的警告“通过获取数据的(浅)副本检测并修复了Invalid.internal.selfref…”这里的type和end是字符,不确定这是否正确expected@Moody_Mudskipper谢谢你的评论。(1) (我认为此警告是由
structure()创建的data.table引起的。
我已更新了答案以避免此问题(2)它们是故意的字符…我觉得正确解析它们将是一个困难且独立的问题。虽然你在回答中解决了这个问题,但我会看一看,看看是否能学到一些新的东西。我会做一个双
cSplit
,如下所示:
cSplit(cSplit(myDT,“info”,“;”,“long”),“info”,“=”[,dcast(.SD,chr+pos~info_1,value.var=“info_2”)]
。或者,相同的概念:
cSplit
后接
tstrsplit
,后接
dcast
cSplit(myDT,“info”,“info”,“long”)[,c(“t1”,“t2”):=tstrsplit(info,=”,fixed=TRUE)][,dcast-SD,chr+pos~t1,value.var=“t2”)]
@A5C1D2H2I1M1N2O1R2T1非常感谢!这两款产品都很棒,双
cSplit
选项有一个特别的:-)
myDT[, (fields) := lapply(patterns, function(x) type.convert(stri_extract(regex = x, info), as.is = TRUE))]
# subset some data from 1000genomes data
tabix -h ftp://ftp-trace.ncbi.nih.gov/1000genomes/ftp/release/20100804/ALL.2of4intersection.20100804.genotypes.vcf.gz 17:1471000-1472000 > myFile.vcf
# zip it and index:
bgzip -c myFile.vcf > myFile.vcf.gz
tabix -p vcf myFile.vcf.gz
bcftools query -f '%CHROM %POS %INFO/AF %INFO/DP \n' myFile.vcf.gz 
17  1471199  1916 0.088
17  1471538  2445 0.016
17  1471611  2733 0.239
17  1471623  2815 0.003
17  1471946  1608 0.007
17  1471959  1612 0.014
17  1471975  1610 0.179