Regex 使用tidyr从列中提取值
我将data.frameRegex 使用tidyr从列中提取值,regex,r,gsub,tidyr,Regex,R,Gsub,Tidyr,我将data.frameannot定义为: annot <- structure(list(Name = c("dd_1", "dd_2", "dd_3","dd_4", "dd_5", "dd_6","dd_7"), GOs = c("C:extracellular space; C:cell body; P:cell migration process; P:NF/ß pathway", "C:Signal transduction; C:nucleus; F:positiv
annot
定义为:
annot <- structure(list(Name = c("dd_1", "dd_2", "dd_3","dd_4", "dd_5", "dd_6","dd_7"), GOs =
c("C:extracellular space; C:cell body; P:cell migration process; P:NF/ß pathway",
"C:Signal transduction; C:nucleus; F:positive regulation; P:single organism; P:positive(+) regulation",
"C:cardiomyceltes; C:intracellular pace; F:putative; F:magnesium ion binding; F:calcium ion binding; P:visual perception; P:blood coagulation",
"F:poly(A) RNA binding; P:DNA-templated transcription, initiation",
"C:ULK1-ATG13-FIP200 complex; F:histone-arginine N-methyltransferase activity; P:single-organism cellular process",
"F:3'-5' DNA helicase activity; P:acetate-CoA ligase activity",
"F:UDP-N-acetylmuramoylalanyl-D-glutamyl-2,6-diaminopimelate-D-alanyl-D-alanine ligase activity; P:oxidoreductase activity, acting on the aldehyde or oxo group of donors, NAD or NADP as acceptor"
)), .Names = c("Name", "GOs"), class = "data.frame", row.names = c(NA,
-7L))
每个条目都包含单词、特殊字符、字母数字字符(C、F、p)。我想拆分与C:xxx对应的所有值;F:yyy:P:zzz
分为单独的列,其对应值如下所示:
Name Component Function P
dd_1 C:extracellular space;C:cell body F:transport carrier P:cell migration process;P:NF/ß pathway
dd_2 C:Signal transduction;C:nucleus F:positive regulation P:single organism;P:positive regulation
dd_3 C:cardiomyceltes;C:intracellular pace F:magnesium ion P:visual perception;P:blood coagulationbinding;F:calcium ion binding;
dd_4 F:poly(A) RNA binding; P:DNA-templated transcription, initiation
dd_5 C:ULK1-ATG13-FIP200 complex F:histone-arginine N-methyltransferase activity P:single-organism cellular process
dd_6 F:3'-5' DNA helicase activity; P:acetate-CoA ligase activity
dd_7 F:UDP-N-acetylmuramoylalanyl-D-glutamyl-2,6-diaminopimelate-D-alanyl-D-alanine ligase activity P:oxidoreductase activity, acting on the aldehyde or oxo group of donors, NAD or NADP as acceptor
我尝试使用tidyr在R中执行命令
separate(annot, GOs, into = c("P", "F", "C"), sep = "[a-z]+=")
但它返回了以下错误:
Error: Values not split into 3 pieces at 1, 2, 3,4
您可以尝试
strsplit
res <- do.call(rbind.data.frame,lapply(strsplit(annot$GOs, ";"),
function(x) tapply(x, sub(':.*', '', x), FUN=paste, collapse=";")))
res1 <- data.frame(Name=annot[,1], setNames(res, c('Component',
'Function', 'P')), stringsAsFactors=FALSE)
res1
# Name Component
#1 dd_1 C:extracellular space;C:cell body
#2 dd_2 C:Signal transduction;C:nucleus
#3 dd_3 C:cardiomyceltes;C:intracellular pace
# Function
#1 F:transport carrier
#2 F:positive regulation
#3 F:putative;F:magnesium ion binding;F:calcium ion binding
# P
#1 P:cell migration process;P:NF/ß pathway
#2 P:single organism;P:positive regulation
#3 P:visual perception;P:blood coagulation
更新
新数据集的每一行都缺少一些元素(即“C”、“F”等)。您可以修改第一个解决方案
res <- do.call(rbind.data.frame,lapply(strsplit(annot$GOs, "; "),function(x){
x1 <- tapply(x, sub(':.*', '', x), FUN=paste, collapse=";")
x1[match(c('C', 'F', 'P'), names(x1))]}))
res1 <- data.frame(Name=annot[,1], setNames(res, c('Component',
'Function', 'P')), stringsAsFactors=FALSE)
head(res1,2)
# Name Component Function
#1 dd_1 C:extracellular space;C:cell body <NA>
#2 dd_2 C:Signal transduction;C:nucleus F:positive regulation
# P
#1 P:cell migration process;P:NF/ß pathway
#2 P:single organism;P:positive(+) regulation
res我认为您最好使用这样一种整洁的格式:
Name GOs
dd_1 C:extracellular space; C:cell body; P:cell migration process; P:NF/ß pathway
dd_2 C:Signal transduction; C:nucleus; F:positive regulation; P:single organism; P:positive(+) regulation
dd_3 C:cardiomyceltes; C:intracellular pace; F:putative; F:magnesium ion binding; F:calcium ion binding; P:visual perception; P:blood coagulation
dd_4 F:poly(A) RNA binding; P:DNA-templated transcription, initiation
dd_5 C:ULK1-ATG13-FIP200 complex; F:histone-arginine N-methyltransferase activity; P:single-organism cellular process
dd_6 F:3'-5' DNA helicase activity; P:acetate-CoA ligase activity
dd_7 F:UDP-N-acetylmuramoylalanyl-D-glutamyl-2,6-diaminopimelate-D-alanyl-D-alanine ligase activity; P:oxidoreductase activity, acting on the aldehyde or oxo group of donors, NAD or NADP as acceptor
library(tidyr)
library(dplyr)
annot %>%
tbl_df() %>%
mutate(GOs = strsplit(GOs, "; ")) %>% # split each GO into a vector
unnest(GOs) %>% # unnest the vectors into multiple rows
separate(GOs, c("type", "value"), ":")
#> Source: local data frame [25 x 3]
#>
#> Name type value
#> 1 dd_1 C extracellular space
#> 2 dd_1 C cell body
#> 3 dd_1 P cell migration process
#> 4 dd_1 P NF/ß pathway
#> 5 dd_2 C Signal transduction
#> 6 dd_2 C nucleus
#> 7 dd_2 F positive regulation
#> 8 dd_2 P single organism
#> 9 dd_2 P positive(+) regulation
#> 10 dd_3 C cardiomyceltes
#> .. ... ... ...
我试过strsplit函数。但是当我运行命令时,它给了我一个错误,说明“strsplit中的错误(annot$GOs,;”):非字符参数“很抱歉混淆-我在问题中添加了dput,并认为该列应该是字符..@docendodiscimus没问题。@docendodiscimus我在实际数据集上尝试了tidyr代码。它给了我错误“error in UseMethod”(“extract_”):没有适用于类“factor”的对象的“extract_”方法。我如何纠正it@akrun我尝试了它,但它在UseMethod(“extract_u2;”)中给出了以下错误:“extract_2;”没有适用于“extract_2;”的方法应用于“类”字符的对象“请检查更新后的解决方案是否有效。@akrun您以前的tidyr对于我提供的示例数据工作得很好。但在我的原始文件中,有很多特殊字符,如(),/,0-9,,并且在may行中,也只有P或F或C,因此tidyr throwed me错误不能对许多条目进行正则表达式,但对于与我之前给出的数据类似的行,它工作得很好。现在我用尽可能多的类型更新了数据集。我还将与您共享该文件。您的新数据集与更新的strsplit解决方案配合得很好。
library(tidyr)
library(dplyr)
annot %>%
tbl_df() %>%
mutate(GOs = strsplit(GOs, "; ")) %>% # split each GO into a vector
unnest(GOs) %>% # unnest the vectors into multiple rows
separate(GOs, c("type", "value"), ":")
#> Source: local data frame [25 x 3]
#>
#> Name type value
#> 1 dd_1 C extracellular space
#> 2 dd_1 C cell body
#> 3 dd_1 P cell migration process
#> 4 dd_1 P NF/ß pathway
#> 5 dd_2 C Signal transduction
#> 6 dd_2 C nucleus
#> 7 dd_2 F positive regulation
#> 8 dd_2 P single organism
#> 9 dd_2 P positive(+) regulation
#> 10 dd_3 C cardiomyceltes
#> .. ... ... ...