使用正则表达式拆分列中的值

Din*_*esh 4 regex split r gsub

我有data.frame有两列,如下所示

dat

    ID                             Details                         
    id_1        box1_homodomain gn=box1 os=homo sapiens p=4 se=1   
    id_2        sox2_plurinet gn=plu os=mus musculus p=5 se=3 
Run Code Online (Sandbox Code Playgroud)

我想在所有ID的"详细信息"列中拆分"os = xxx"和gn ="yyy",并将其打印如下:

    Id   Description        gn      os               
   Îd_1  box1_homodomain    box1    homo sapiens   
   Id_2  sox2_plurinet      plu     mouse musculus 
Run Code Online (Sandbox Code Playgroud)

我尝试在R中使用gsub方法,但我无法将os = homo sapiens和gn = box1分成各自的列.我用的是以下R代码

dat$gn=gsub('^[gn=][A-z][A-z]`,dat$Details)
dat$os=gsub('^[os=][A-z][A-z]`,dat$Details)
Run Code Online (Sandbox Code Playgroud)

任何人都可以告诉我什么是错的,如何纠正.请帮助我.

提前致谢

tal*_*lat 5

这是tidyr的一个选项:

library(tidyr)
# specify the new column names:
vars <- c("Description", "gn", "os")
# then separate the "Details" column according to regex and drop extra columns:
separate(dat, Details, into = vars, sep = "[A-Za-z]+=", extra = "drop")
#    ID      Description    gn            os
#1 id_1 box1_homodomain  box1  homo sapiens 
#2 id_2   sox2_plurinet   plu  mus musculus
Run Code Online (Sandbox Code Playgroud)


G. *_*eck 5

1) sub 和 gsub要使用subgsub来完成此操作,请尝试这样做。请注意,每个正则表达式应与所有正则表达式匹配dat$Details,以便当我们将其替换为捕获组时,仅保留捕获组。对于dat$GO问题评论中的 as ,我们删除所有直到但不包括 的内容,用逗号P:替换所有出现的,并删除并删除分号及其后的所有内容。同样对于和:;PP:FC

data.frame(dat[1], 
   Description = sub(" .*", "", dat$Details),
   gn = sub(".*gn=(.*) os=.*", "\\1", dat$Details),
   os = sub(".*os=(.*) p=.*", "\\1", dat$Details),
   P = gsub("P:|;.*", "", gsub(";P:", ",", sub(".*?P:", "P:", dat$GO))),
   F = gsub("F:|;.*", "", gsub(";F:", ",", sub(".*?F:", "F:", dat$GO))),
   C = gsub("C:|;.*", "", gsub(";C:", ",", sub(".*?C:", "C:", dat$GO))))
Run Code Online (Sandbox Code Playgroud)

给予:

    ID     Description   gn           os       P       F       C
1 id_1 box1_homodomain box1 homo sapiens p_1,p_2     F_1 C_1,C_2
2 id_2   sox2_plurinet  plu mus musculus     p_1 F_1,F_2     C_1
Run Code Online (Sandbox Code Playgroud)

2) read.pattern使用gsubfn 包中的(link) 进行处理dat$Details要容易一些,因为可以定义一个则表达式,其捕获组代表感兴趣的字段。通过使用(link)提取字段,然后将它们连接在一起(与和字段类似),也可以简化 的处理:read.pattern dat$GOP:...strapplyc pasteFC

library(gsubfn)

Sub <- function(string, pat) sapply(strapplyc(string, pat), paste, collapse = ",")

DF <- read.pattern(text = as.character(dat$Details), 
        pattern = "(.*) gn=(.*) os=(.*) p=",
        col.names = c("Description", "gn", "os"),
        as.is = TRUE)

cbind(dat[1], DF,
      P = Sub(dat$GO, "P:(.*?);"),
      F = Sub(dat$GO, "F:(.*?);"),
      C = Sub(dat$GO, "C:(.*?);"))
Run Code Online (Sandbox Code Playgroud)

给予:

    ID     Description   gn           os       P       F       C
1 id_1 box1_homodomain box1 homo sapiens p_1,p_2     F_1 C_1,C_2
2 id_2   sox2_plurinet  plu mus musculus     p_1 F_1,F_2     C_1
Run Code Online (Sandbox Code Playgroud)

以下是 中使用的正则表达式的可视化read.pattern

(.*) gn=(.*) os=(.*) p=
Run Code Online (Sandbox Code Playgroud)

正则表达式可视化

调试演示

笔记

1)如果该dat$Details列已经是字符,我们可以省略as.character。如果结果中as.is=TRUE可以包含列,我们也可以省略。factor

2)问题中的样本输出有,mouse但输入有mus。我们假设这mus两种情况都应该如此。

3)我们用它来dat

dat <-
structure(list(ID = c("id_1", "id_2"), 
Details = c("box1_homodomain gn=box1 os=homo sapiens p=4 se=1", 
"sox2_plurinet gn=plu os=mus musculus p=5 se=3"), 
GO = c("P:p_1;P:p_2;F:F_1;C:C_1;C:C_2;  ", 
"P:p_1;F:F_1;F:F_2;C:C_1;")), .Names = c("ID", "Details", 
"GO"), class = "data.frame", row.names = c(NA, -2L))
Run Code Online (Sandbox Code Playgroud)

将来请dput(dat)在问题中发布结果。