Поиск шаблона в R - PullRequest
       1

Поиск шаблона в R

0 голосов
/ 25 сентября 2018

У меня есть два кадра данных, как показано ниже.DF1 немного грязный (как вы можете видеть ниже), имеет несколько значений из DF2, объединенных в один столбец.

DF1
SRNo.      Value
1      1ABCD2EFGH3IJKL
2      1ABCD2EFGH3IJKL/7MLPO0OKMN8MNBV
3      3ABCD4EFGH5IJKL
4      3ABCD4EFGH5IJKL/1ABCD2EFGH3IJKL
5      7MLPO0OKMN8MNBV/9IUYT7HGFD3LKJH
DF2
SRNo.   Value
1   1ABCD2EFGH3IJKL
2   3ABCD4EFGH5IJKL
3   6PQRS7TUVW8XYZA
4   5FGHI9XUZX1RATP
5   9AGTY6UGFW0AAUU
6   6TEYD7RARA8MHAT
7   9IUYT7HGFD3LKJH

Я хочу выполнить поиск по столбцу значений в обоих наборах данных.Вот что я пытаюсь сделать.

i) Для строк 1 и 3 в DF1 это простой поиск в DF2.Я ожидаю, что код вернет эти искомые значения.
ii) Для строки № 3 в DF1 только первая часть строки соответствует значению в DF2.Я ожидаю, что код вернет только первую часть.
iii) Для строки № 4 в DF1 обе части строки соответствуют значениям в DF2.В этом случае я хочу, чтобы первая соответствующая часть строки была сохранена
iv) Для строки № 5 вторая часть в строке соответствует значению в DF2.Я ожидаю, что код вернет 2-ую часть строки.

У меня около 47000 строк в первом наборе данных и более 300 000 во втором наборе данных и, конечно же, в обоих наборах есть другие столбцы.Я пробовал это несколькими способами, используя str_split / str_match, но не смог выполнить то, что я хочу.Каждое предложение приветствуется.Остальная часть кода написана на R.

Спасибо

Ответы [ 2 ]

0 голосов
/ 25 сентября 2018

Решение для Data.table

df1 <- read.table(text="SRNo.      Value
                  1      1ABCD2EFGH3IJKL
                  2      1ABCD2EFGH3IJKL/7MLPO0OKMN8MNBV
                  3      3ABCD4EFGH5IJKL
                  4      3ABCD4EFGH5IJKL/1ABCD2EFGH3IJKL
                  5      7MLPO0OKMN8MNBV/9IUYT7HGFD3LKJH", header = T, stringsAsFactors = F)

df2 <- read.table( text = "SRNo.   Value
                   1   1ABCD2EFGH3IJKL
                   2   3ABCD4EFGH5IJKL
                   3   6PQRS7TUVW8XYZA
                   4   5FGHI9XUZX1RATP
                   5   9AGTY6UGFW0AAUU
                   6   6TEYD7RARA8MHAT
                   7   9IUYT7HGFD3LKJH", header = T, stringsAsFactors = F )

library( data.table )
setDT(df1)[, c( "Value1", "Value2" ) := tstrsplit( Value, "/", fixed = TRUE)]
setDT(df2)

resultv1 <- df2[ df1, on = c( Value = "Value1"), nomatch = 0L ]
resultv2 <- df2[ df1, on = c( Value = "Value2"), nomatch = 0L ]

result <- rbindlist( list( resultv1, resultv2 ) )[!duplicated( i.SRNo.)]

Сравнение его с решением от @Paul показывает аналогичные времена выполнения (~ 2,5 миллисекунды) .. Но иногда data.table меня удивляет на больших наборах данных ..

Если память становится проблемой, вы можете сделать все это за один раз:

rbindlist( list( setDT(df2)[ setDT(df1)[, c( "Value1", "Value2" ) := tstrsplit( Value, "/", fixed = TRUE)], 
                               on = c( Value = "Value1"), nomatch = 0L ], 
                   setDT(df2)[ setDT(df1)[, c( "Value1", "Value2" ) := tstrsplit( Value, "/", fixed = TRUE)], 
                               on = c( Value = "Value2"), nomatch = 0L ] ) )[!duplicated( i.SRNo.)]
0 голосов
/ 25 сентября 2018

Первый шаг - tidyr::separate() ваш DF1 в "/".Затем я использовал dplyr::case_when(), чтобы увидеть, было ли совпадение между первым из перечисленных элементов в DF2 с %in%;если не было, тогда сверяйте со вторым.Я использовал dplyr::mutate(), чтобы добавить результаты к DF1 в dat.

library(dplyr)
library(tidyr)

DF1 <- data.frame("SRNo." = 1:5, Value = c("1ABCD2EFGH3IJKL","1ABCD2EFGH3IJKL/7MLPO0OKMN8MNBV","3ABCD4EFGH5IJKL","3ABCD4EFGH5IJKL/1ABCD2EFGH3IJKL","7MLPO0OKMN8MNBV/9IUYT7HGFD3LKJH"), stringsAsFactors = F) %>% tbl_df()

DF2 <- data.frame("SRNo." = 1:7, Value = c("1ABCD2EFGH3IJKL","3ABCD4EFGH5IJKL","6PQRS7TUVW8XYZA","5FGHI9XUZX1RATP","9AGTY6UGFW0AAUU","6TEYD7RARA8MHAT","9IUYT7HGFD3LKJH"), stringsAsFactors = F) %>%tbl_df()

DF1 %>%
  separate(Value, c("Value1", "Value2"), sep = "/")  %>%
  mutate(dat = case_when(
    Value1 %in% DF2$Value ~ Value1,
    Value2 %in% DF2$Value ~ Value2,
    TRUE ~ NA_character_
  ))

# # A tibble: 5 x 4
#   SRNo. Value1          Value2          dat            
#   <int> <chr>           <chr>           <chr>          
# 1     1 1ABCD2EFGH3IJKL NA              1ABCD2EFGH3IJKL
# 2     2 1ABCD2EFGH3IJKL 7MLPO0OKMN8MNBV 1ABCD2EFGH3IJKL
# 3     3 3ABCD4EFGH5IJKL NA              3ABCD4EFGH5IJKL
# 4     4 3ABCD4EFGH5IJKL 1ABCD2EFGH3IJKL 3ABCD4EFGH5IJKL
# 5     5 7MLPO0OKMN8MNBV 9IUYT7HGFD3LKJH 9IUYT7HGFD3LKJH
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...