Подстановка символьной строки и возвращаемой строки - PullRequest
1 голос
/ 20 июня 2019

Мне было интересно, было ли чистое решение с использованием data.table для решения следующей проблемы, возможно, с использованием других пакетов, таких как stringr.

Предположим, у меня есть следующая таблица данных

DT <- data.table(name = c("Carlos", "Henry", "John"), 
    ID = c("US115115, CH123232, AB155, US4445", "CH112, BB53", "US57677777"))

Это выглядит так:

     name                                ID
1: Carlos US115115, CH123232, AB155, US4445
2:  Henry                       CH112, BB53
3:   John                        US57677777

Я хочу создать еще один столбец ID2, скажем, чтоберет идентификатор столбца и извлекает только «американские идентификаторы» и создает новый столбец, чтобы итоговая таблица данных выглядела следующим образом:

     name                                ID              ID2
1: Carlos US115115, CH123232, AB155, US4445 US115115, US4445
2:  Henry                       CH112, BB53               NA
3:   John                        US57677777       US57677777                     

и где каждый элемент является строкой.Мне удалось зашифровать версию, в которой она берет первую «американскую идентификацию» и отбрасывает остальные, но я не смогла найти решение, которое обрабатывает множественность.

Любая помощь будет принята с благодарностью!

Ответы [ 3 ]

4 голосов
/ 20 июня 2019

Возможный подход:

DT[, ID2 := sapply(strsplit(ID, ","), 
    function(s) paste(s[grepl("\\s*US", s)], collapse=","))]

Выход:

     name                                ID              ID2
1: Carlos US115115, CH123232, AB155, US4445 US115115, US4445
2:  Henry                       CH112, BB53                 
3:   John                        US57677777       US57677777
2 голосов
/ 20 июня 2019

Вот несколько советов, вдохновленных @thelatemail и @ chinsoon12

DT$ID1 <- sapply(strsplit(DT$ID, ",\\s*"), function(x) 
                            toString(grep("^US", x, value = TRUE)))
DT
#     name                                ID              ID1
#1: Carlos US115115, CH123232, AB155, US4445 US115115, US4445
#2:  Henry                       CH112, BB53                 
#3:   John                        US57677777       US57677777

Выше мы фильтруем, используя grep, мы также можем использовать startsWith, чтобы сделать то же самое

sapply(strsplit(DT$ID, ",\\s*"), function(x) toString(x[startsWith(x, "US")]))

Вы можете включить оба вышеупомянутых параметра в цепочку dplyr, однако другой вариант, использующий dplyr и tidyr, будет использовать separate_rows, что может быть излишним для этого конкретного вопроса. Мы можем использовать str_subset из stringr, что совпадает с grep("^US", x, value = TRUE).

library(dplyr)
library(tidyr)

DT %>%
  separate_rows(ID) %>%
  group_by(name) %>%
  summarise(ID1 = toString(ID), 
            ID2 = toString(stringr::str_subset(ID, "^US")))
0 голосов
/ 20 июня 2019

Мы можем либо использовать str_extract, чтобы извлечь слова, начинающиеся с "US"

library(stringr)
DT[, ID2 := sapply(str_extract_all(ID, "\\bUS\\S*"), toString)]
DT
#     name                                ID               ID2
#1: Carlos US115115, CH123232, AB155, US4445 US115115,, US4445
#2:  Henry                       CH112, BB53                  
#3:   John                        US57677777        US57677777

Или использовать gsub

DT[, ID2 := gsub("(\\bUS\\S*)(*SKIP)(*F)|.", "", ID, perl = TRUE)]

Или использовать tidyverse

library(tidyverse)
DT %>%
    mutate(ID2 = str_extract_all(ID, "\\bUS\\S*") %>%
                   map(toString))

Или с base R с использованием gregexpr

DT$ID2 <- sapply(regmatches(DT$ID, gregexpr("\\bUS\\S*", DT$ID)), toString)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...