Разделить строки символов с различными комбинациями на основе буквы в R - PullRequest
1 голос
/ 13 февраля 2020

У меня большой фрейм данных с символьным столбцом, содержащим другую комбинацию строк.

Например,

**Column1**
1.0.01.01 
1.02.04.03 | E1.3  
G1.2 | 5.01.03.2
30.02.01.04.02 
I.1
10.04.03 | H1.256

Единственные значения, которые меня интересуют, - это значения, начинающиеся с письмо. Мой желаемый результат должен выглядеть следующим образом:

**Column1**
NA
E1.3  
G1.2
NA
I.1
H1.256

Testdata:

structure(list(Column1 = c("1.0.01.01", "1.02.04.03 | E1.3",
"G1.2 | 5.01.03.2", "30.02.01.04.02", "I.1", "10.04.03 | H1.256")), 
class = "data.frame", row.names = c(NA, -6L)) 

Я думаю, что решение может быть очень простым с grepl или подобными командами, но в данный момент я пропускаю правильная идея для начала.

Ответы [ 4 ]

4 голосов
/ 13 февраля 2020

Вы можете использовать ^[[:alpha:]], чтобы найти с помощью grep, если оно начинается с символа.

unlist(lapply(strsplit(x$Column1, " \\| "), function(x)
   grep("^[[:alpha:]]", x, value = TRUE)[1]))
#[1] NA       "E1.3"   "G1.2"   NA       "I.1"    "H1.256"

Если нет окружающих пробелов:

unlist(lapply(strsplit(x$Column1, "\\|"), function(x) 
   grep("^[[:alpha:]]", trimws(x), value = TRUE)[1]))

И в В случае, если в каждой строке более одного совпадения (с "" вместо NA):

unlist(lapply(strsplit(x$Column1, " \\| "), function(x)
  paste(grep("^[[:alpha:]]", x, value = TRUE), collapse = " | ")))

или с использованием sub:

sub("^.*\\b([[:alpha:]][^ ]+).*$|.*", "\\1", x$Column1)

Или с использованием regexec и regmatches

tt <- regmatches(x$Column1, regexec("\\b[[:alpha:]][^ ]*", x$Column1))
tt[lengths(tt)==0] <- NA;
unlist(tt)
2 голосов
/ 13 февраля 2020

Вот что я попробовал. Ваши данные называются mydf.

library(tidyverse)
library(stringi)

mutate(mydf,
       newcol = unlist(stri_extract_all_regex(str = Column1,
                                              pattern = "(?<=\\s|^)[A-Z].*?(?=\\s|$)")))

            Column1 newcol
1         1.0.01.01   <NA>
2 1.02.04.03 | E1.3   E1.3
3  G1.2 | 5.01.03.2   G1.2
4    30.02.01.04.02   <NA>
5               I.1    I.1
6 10.04.03 | H1.256 H1.256

Другой способ, которым я пользовался, был следующим:

mutate(mydf, group = 1:n()) %>% 
separate_rows(Column1, sep = "\\s\\|\\s") %>% 
filter(grepl(x = Column1, pattern = "^[A-Z]")) %>% 
complete(group = 1:nrow(mydf))

  group Column1
  <int> <chr>  
1     1 NA     
2     2 E1.3   
3     3 G1.2   
4     4 NA     
5     5 I.1    
6     6 H1.256
2 голосов
/ 13 февраля 2020

Вы можете попробовать этот подход, предполагая, что df - это ваш фрейм данных, а Column1 - это имя вашего столбца.

stringr::str_extract(df$Column1, '[a-zA-Z]+\\d*\\.\\d+')

[a-zA-Z] поиск одного или нескольких алфавитов, за которыми следует ноль или более совпадений цифр, затем точка и затем цифры

Вывод :

[1] NA       "E1.3"   "G1.2"   NA       "I.1"    "H1.256"
0 голосов
/ 13 февраля 2020

Вот еще одно базовое решение R, использующее regmatches

df <- within(df, 
             Column2 <- unlist(replace(u<<-regmatches(Column1,
                                                      gregexpr("\\b[[:alpha:]][\\.\\d]+\\b",
                                                               Column1,perl = TRUE)),
                                       !lengths(u),
                                       NA)))

, такое что

> df
            Column1 Column2
1         1.0.01.01    <NA>
2 1.02.04.03 | E1.3    E1.3
3  G1.2 | 5.01.03.2    G1.2
4    30.02.01.04.02    <NA>
5               I.1     I.1
6 10.04.03 | H1.256  H1.256
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...