根据多个正则表达式子字符串对变量进行排序

问题描述 投票:2回答:5

我试图在R中订购一个变量,它是一个包含三个我想要订购的子串的文件名列表。文件名的格式如下:

MAF001.incMHC.zPGS.S1
MAF002.incMHC.zPGS.S1
MAF003.incMHC.zPGS.S1
MAF001.incMHC.zPGS.S2
MAF002.incMHC.zPGS.S2
MAF003.incMHC.zPGS.S2
MAF001.noMHC_incRS148.zPGS.S1
MAF002.noMHC_incRS148.zPGS.S1
MAF003.noMHC_incRS148.zPGS.S1
MAF001.noMHC_incRS148.zPGS.S2
MAF002.noMHC_incRS148.zPGS.S2
MAF003.noMHC_incRS148.zPGS.S2
MAF001.noMHC.zPGS.S1
MAF002.noMHC.zPGS.S1
MAF003.noMHC.zPGS.S1
MAF001.noMHC.zPGS.S2
MAF002.noMHC.zPGS.S2
MAF003.noMHC.zPGS.S2

我想首先在MAF子字符串,然后是MHC子字符串,然后是S子字符串上订购此列表,这样的顺序是:

MAF001.incMHC.zPGS.S1
MAF001.noMHC_incRS148.zPGS.S1
MAF001.noMHC.zPGS.S1
MAF001.incMHC.zPGS.S2
MAF001.noMHC_incRS148.zPGS.S2
MAF001.noMHC.zPGS.S2
MAF002.incMHC.zPGS.S1
MAF002.noMHC_incRS148.zPGS.S1
MAF002.noMHC.zPGS.S1
MAF002.incMHC.zPGS.S2
MAF002.noMHC_incRS148.zPGS.S2
MAF002.noMHC.zPGS.S2
MAF003.incMHC.zPGS.S1
MAF003.noMHC_incRS148.zPGS.S1
MAF003.noMHC.zPGS.S1
MAF003.incMHC.zPGS.S2
MAF003.noMHC_incRS148.zPGS.S2
MAF003.noMHC.zPGS.S2

在看到关于单个子串的这个问题的答案后,我已经玩过gsub:R Sort strings according to substring

但我不知道如何将这个想法扩展到字符串中的多个子串(混合字符和数字类)。

r regex sorting substring
5个回答
2
投票

这是基础R中的单行:

bar <- foo[order(sapply(strsplit(foo, "\\."), function(x) paste(x[1], x[4])))]
head(data.frame(result = bar), 10)

                          result
1          MAF001.incMHC.zPGS.S1
2  MAF001.noMHC_incRS148.zPGS.S1
3           MAF001.noMHC.zPGS.S1
4          MAF001.incMHC.zPGS.S2
5  MAF001.noMHC_incRS148.zPGS.S2
6           MAF001.noMHC.zPGS.S2
7          MAF002.incMHC.zPGS.S1
8  MAF002.noMHC_incRS148.zPGS.S1
9           MAF002.noMHC.zPGS.S1
10         MAF002.incMHC.zPGS.S2

说明:

  • .使用strsplit分割字符串:strsplit(foo, "\\.")
  • 提取并组合元素1和4:paste(x[1], x[4])
  • 使用order获取所有组合的顺序
  • foo[]获取相应的值

数据(foo):

c("MAF001.incMHC.zPGS.S1", "MAF002.incMHC.zPGS.S1", "MAF003.incMHC.zPGS.S1", 
"MAF001.incMHC.zPGS.S2", "MAF002.incMHC.zPGS.S2", "MAF003.incMHC.zPGS.S2", 
"MAF001.noMHC_incRS148.zPGS.S1", "MAF002.noMHC_incRS148.zPGS.S1", 
"MAF003.noMHC_incRS148.zPGS.S1", "MAF001.noMHC_incRS148.zPGS.S2", 
"MAF002.noMHC_incRS148.zPGS.S2", "MAF003.noMHC_incRS148.zPGS.S2", 
"MAF001.noMHC.zPGS.S1", "MAF002.noMHC.zPGS.S1", "MAF003.noMHC.zPGS.S1", 
"MAF001.noMHC.zPGS.S2", "MAF002.noMHC.zPGS.S2", "MAF003.noMHC.zPGS.S2"
)

1
投票

使用tidyrdplyr

library(tidyr)
library(dplyr)

df <- data.frame(filenames = c(...))

pattern = "^([^.]+)\\.([^.]+)"
df %>%
  extract(filenames, 
          into = c("maf", "mhc"), 
          regex = pattern, remove = FALSE) %>%
  arrange(maf, mhc) %>%
  select(filenames)

哪个收益率

                       filenames
1          MAF001.incMHC.zPGS.S1
2          MAF001.incMHC.zPGS.S2
3           MAF001.noMHC.zPGS.S1
4           MAF001.noMHC.zPGS.S2
5  MAF001.noMHC_incRS148.zPGS.S1
6  MAF001.noMHC_incRS148.zPGS.S2
7          MAF002.incMHC.zPGS.S1
8          MAF002.incMHC.zPGS.S2
9           MAF002.noMHC.zPGS.S1
10          MAF002.noMHC.zPGS.S2
11 MAF002.noMHC_incRS148.zPGS.S1
12 MAF002.noMHC_incRS148.zPGS.S2
13         MAF003.incMHC.zPGS.S1
14         MAF003.incMHC.zPGS.S2
15          MAF003.noMHC.zPGS.S1
16          MAF003.noMHC.zPGS.S2
17 MAF003.noMHC_incRS148.zPGS.S1
18 MAF003.noMHC_incRS148.zPGS.S2

0
投票

此结果与您想要的输出相匹配,但它只根据MAFS进行排序。我不明白如何使用MHC字符串进行排序,如果这个答案不能满足您的需求,请详细说明该部分。

library(stringr)
maf <- str_extract(filenames, "MAF\\d+\\.")
mhc <- str_extract(filenames, "\\..*MHC.*\\.")
s <- str_extract(filenames, "S\\d+$")

library(magrittr)
library(dplyr)

data.frame(filenames, maf, mhc, s) %>% 
  arrange(maf, s) %>% 
  select(filenames)

输出是:

                       filenames
1          MAF001.incMHC.zPGS.S1
2          MAF001.incMHC.zPGS.S2
3           MAF001.noMHC.zPGS.S1
4           MAF001.noMHC.zPGS.S2
5  MAF001.noMHC_incRS148.zPGS.S1
6  MAF001.noMHC_incRS148.zPGS.S2
7          MAF002.incMHC.zPGS.S1
8          MAF002.incMHC.zPGS.S2
9           MAF002.noMHC.zPGS.S1
10          MAF002.noMHC.zPGS.S2
11 MAF002.noMHC_incRS148.zPGS.S1
12 MAF002.noMHC_incRS148.zPGS.S2
13         MAF003.incMHC.zPGS.S1
14         MAF003.incMHC.zPGS.S2
15          MAF003.noMHC.zPGS.S1
16          MAF003.noMHC.zPGS.S2
17 MAF003.noMHC_incRS148.zPGS.S1
18 MAF003.noMHC_incRS148.zPGS.S2

filenames在哪里

filenames <- read.table(text="MAF001.incMHC.zPGS.S1
MAF002.incMHC.zPGS.S1
MAF003.incMHC.zPGS.S1
MAF001.incMHC.zPGS.S2
MAF002.incMHC.zPGS.S2
MAF003.incMHC.zPGS.S2
MAF001.noMHC_incRS148.zPGS.S1
MAF002.noMHC_incRS148.zPGS.S1
MAF003.noMHC_incRS148.zPGS.S1
MAF001.noMHC_incRS148.zPGS.S2
MAF002.noMHC_incRS148.zPGS.S2
MAF003.noMHC_incRS148.zPGS.S2
MAF001.noMHC.zPGS.S1
MAF002.noMHC.zPGS.S1
MAF003.noMHC.zPGS.S1
MAF001.noMHC.zPGS.S2
MAF002.noMHC.zPGS.S2
MAF003.noMHC.zPGS.S2", header=FALSE, stringsAsFactors=FALSE)

0
投票

这里已经添加了许多好的解决方案。我正在添加另一个仅基于vector的使用。

注意:OP打算对MAFMHCS子串进行排序。我坚持用这条规则对这三个人进行排序。因此,我的答案结果可能与其他答案不符。

该方法:

  1. 使用regmatches在OP中查找每个描述的子字符串
  2. 使用paste准备基于sort可以执行的字符串
  3. 使用setNames设置矢量名称
  4. 在名字上排序vectorv[order(names(setNames(v, paste(regmatches(v, regexpr("^MAF\\d+", v, perl = TRUE)), regmatches(v, regexpr("\\w*MHC\\w*", v, perl = TRUE)), regmatches(v, regexpr("\\w+\\d+$", v, perl = TRUE)) ))))] #Result [1] "MAF001.incMHC.zPGS.S1" [2] "MAF001.incMHC.zPGS.S2" [3] "MAF001.noMHC.zPGS.S1" [4] "MAF001.noMHC.zPGS.S2" [5] "MAF001.noMHC_incRS148.zPGS.S1" [6] "MAF001.noMHC_incRS148.zPGS.S2" [7] "MAF002.incMHC.zPGS.S1" [8] "MAF002.incMHC.zPGS.S2" [9] "MAF002.noMHC.zPGS.S1" [10] "MAF002.noMHC.zPGS.S2" [11] "MAF002.noMHC_incRS148.zPGS.S1" [12] "MAF002.noMHC_incRS148.zPGS.S2" [13] "MAF003.incMHC.zPGS.S1" [14] "MAF003.incMHC.zPGS.S2" [15] "MAF003.noMHC.zPGS.S1" [16] "MAF003.noMHC.zPGS.S2" [17] "MAF003.noMHC_incRS148.zPGS.S1" [18] "MAF003.noMHC_incRS148.zPGS.S2"

数据

v <- c("MAF001.incMHC.zPGS.S1", "MAF001.noMHC_incRS148.zPGS.S1", "MAF001.noMHC.zPGS.S1", 
       "MAF001.incMHC.zPGS.S2", "MAF001.noMHC_incRS148.zPGS.S2", "MAF001.noMHC.zPGS.S2", 
       "MAF002.incMHC.zPGS.S1", "MAF002.noMHC_incRS148.zPGS.S1", "MAF002.noMHC.zPGS.S1", 
       "MAF002.incMHC.zPGS.S2", "MAF002.noMHC_incRS148.zPGS.S2", "MAF002.noMHC.zPGS.S2", 
       "MAF003.incMHC.zPGS.S1", "MAF003.noMHC_incRS148.zPGS.S1", "MAF003.noMHC.zPGS.S1", 
       "MAF003.incMHC.zPGS.S2", "MAF003.noMHC_incRS148.zPGS.S2", "MAF003.noMHC.zPGS.S2"
)

0
投票

我有一个专门为这样的任务设计的功能:

功能

reg_sort <- function(x,...,verbose=F) {
    ellipsis <-   sapply(as.list(substitute(list(...)))[-1], deparse, simplify="array")
    reg_list <-   paste0(ellipsis, collapse=',')
    reg_list %<>% strsplit(",") %>% unlist %>% gsub("\\\\","\\",.,fixed=T)
    pattern  <-   reg_list %>% map_chr(~sub("^-\\\"","",.) %>% sub("\\\"$","",.) %>% sub("^\\\"","",.) %>% trimws)
    descInd  <-   reg_list %>% map_lgl(~grepl("^-\\\"",.)%>%as.logical)

    reg_extr <-   pattern %>% map(~str_extract(x,.)) %>% c(.,list(x)) %>% as.data.table
    reg_extr[] %<>% lapply(., function(x) type.convert(as.character(x), as.is = TRUE))

    map(rev(seq_along(pattern)),~{reg_extr<<-reg_extr[order(reg_extr[[.]],decreasing = descInd[.])]})

    if(verbose) { tmp<-lapply(reg_extr[,.SD,.SDcols=seq_along(pattern)],unique);names(tmp)<-pattern;tmp %>% print }

    return(reg_extr[[ncol(reg_extr)]])
}

数据:

vec <- c("MAF001.incMHC.zPGS.S1", "MAF002.incMHC.zPGS.S1", "MAF003.incMHC.zPGS.S1", 
  "MAF001.incMHC.zPGS.S2", "MAF002.incMHC.zPGS.S2", "MAF003.incMHC.zPGS.S2", 
  "MAF001.noMHC_incRS148.zPGS.S1", "MAF002.noMHC_incRS148.zPGS.S1", 
  "MAF003.noMHC_incRS148.zPGS.S1", "MAF001.noMHC_incRS148.zPGS.S2", 
  "MAF002.noMHC_incRS148.zPGS.S2", "MAF003.noMHC_incRS148.zPGS.S2", 
  "MAF001.noMHC.zPGS.S1", "MAF002.noMHC.zPGS.S1", "MAF003.noMHC.zPGS.S1", 
  "MAF001.noMHC.zPGS.S2", "MAF002.noMHC.zPGS.S2", "MAF003.noMHC.zPGS.S2"
)

呼叫:

reg_sort(x=vec, "^.*?(?=\\.)","(?<=\\.).*(?<=\\.S)","S\\d+$")

结果:(一个字符向量)

1          MAF001.incMHC.zPGS.S1
2          MAF001.incMHC.zPGS.S2
3           MAF001.noMHC.zPGS.S1
4           MAF001.noMHC.zPGS.S2
5  MAF001.noMHC_incRS148.zPGS.S1
6  MAF001.noMHC_incRS148.zPGS.S2
7          MAF002.incMHC.zPGS.S1
8          MAF002.incMHC.zPGS.S2
9           MAF002.noMHC.zPGS.S1
10          MAF002.noMHC.zPGS.S2
11 MAF002.noMHC_incRS148.zPGS.S1
12 MAF002.noMHC_incRS148.zPGS.S2
13         MAF003.incMHC.zPGS.S1
14         MAF003.incMHC.zPGS.S2
15          MAF003.noMHC.zPGS.S1
16          MAF003.noMHC.zPGS.S2
17 MAF003.noMHC_incRS148.zPGS.S1
18 MAF003.noMHC_incRS148.zPGS.S2

其他功能包括:

  • 降序排序:(添加- infront)reg_sort(x=vec, -"^.*?(?=\\.)","(?<=\\.).*(?<=\\.S)",-"S\\d+$")
  • 详细模式:reg_sort(x=vec, "^.*?(?=\\.)","(?<=\\.).*(?<=\\.S)","S\\d+$",verbose=T)(查看/检查regEx模式提取的内容以便排序)
© www.soinside.com 2019 - 2024. All rights reserved.