Mutlistep Cleaning / Regex: замена и порция экстракта перед сепаратором - PullRequest
0 голосов
/ 25 июня 2018

У меня есть матрица M с именами строк, как показано ниже;

S003_T1_p555
S003_T2_p456
S004_T3_p785
S004_T4_p426
SuperSMART_27_T1_p112
SuperSMART_27_T2_p414
SuperSMART_42_T3_p155
SuperSMART_42_T5_p775

Я хотел бы сделать функцию для:

  1. замены SuperSMART_ на S в строках, что это так
  2. , затем извлекают только символы перед первым _ в качестве ключей и присваивают уникальное имя каждому подобному человеку

Так что оба S003_T1_p555 иS003_T2_p456 становятся "group1", S004_T3_p785 и S004_T4_p426 "group2" и т. Д.

MWE

nms <- c("S003_T1_p555", "S003_T2_p456", "S004_T3_p785", "S004_T4_p426", 
    "SuperSMART_27_T1_p112", "SuperSMART_27_T2_p414", 
    "SuperSMART_42_T3_p155", "SuperSMART_42_T5_p775")

M <- matrix(
    seq_along(nms),
    dimnames = list(
        nms,
        'x'    
    )
)

1 Ответ

0 голосов
/ 27 июня 2018
library(tidyverse)

as.data.frame(M, stringsAsFactors = FALSE) %>%
    rownames_to_column('id') %>%
    mutate(
        id = gsub('SuperSMART_', 'S', id), 
        id = gsub('(^S)(\\d{2})(_)', '\\10\\2\\3', id, perl = TRUE) 
    ) %>%
    separate(id, into = c('S', 'R', 'p'), sep = '_', remove = FALSE) %>%  
    mutate(., group = group_indices(., S))

##             id    S  R    p x group
## 1 S003_T1_p555 S003 T1 p555 1     1
## 2 S003_T2_p456 S003 T2 p456 2     1
## 3 S004_T3_p785 S004 T3 p785 3     2
## 4 S004_T4_p426 S004 T4 p426 4     2
## 5 S027_T1_p112 S027 T1 p112 5     3
## 6 S027_T2_p414 S027 T2 p414 6     3
## 7 S042_T3_p155 S042 T3 p155 7     4
## 8 S042_T5_p775 S042 T5 p775 8     4


## If you really want it as a function:
normalize_data <- function(m, ..) {
    as.data.frame(m, stringsAsFactors = FALSE) %>%
        tibble::rownames_to_column('id') %>%
        dplyr::mutate(
            id = gsub('SuperSMART_', 'S', id), 
            id = gsub('(^S)(\\d{2})(_)', '\\10\\2\\3', id, perl = TRUE) 
        ) %>%
        tidyr::separate(id, into = c('S', 'R', 'p'), sep = '_', remove = FALSE) %>%  
        dplyr::mutate(., group = dplyr::group_indices(., S))
}

Итак, это групповой снимок, обозначаемый круглыми скобками '(^S)(\d{2})(_)'.Есть 3 группы в плен.1: (^S), 2: (\d{2}), 3: (_).Первый говорит, хватай с начала (^) и S.Вторая группа говорит, что захватите после этого, где есть ровно 2 цифры (\\d{2}), а затем третья группа говорит, что за ней должно следовать подчеркивание.

Так что S27_T2_p414 будет соответствовать этому, но S004_T3_p785 не будет.

Для замены '\10\2\3' .... Если он соответствует '(^S)(\d{2})(_)', мы можем использовать perl = TRUE для замены захвата группы (обозначено скобками выше. \1 соответствует (^S);\2 соответствует (\d{2}) И \3 идет с (_). Мы можем вставлять вещи между группами захвата. Этот метод называется обратная ссылка . В этом случае я вставляю дополнительный ноль междупервая группа захвата и вторая для обеспечения того, чтобы все числа имели 3 цифры. Это предполагает, что самое большее у вас есть 3 цифры в строке после S.

...