Лучшее решение для проверки элементов одного символьного вектора с другим символьным вектором, используя Tidyverse? - PullRequest
0 голосов
/ 29 октября 2019

Привет!
Моя цель состоит в том, чтобы сравнить два символьных вектора - основным является синонимы и другие миксовые имена. Строковые элементы в именах соединений не совпадают точно с тем, что есть в синонимах, поэтому требуется некоторое сравнение строк. Моя цель состоит в том, чтобы извлечь элементы в синонимах, которые имеют нечто похожее на то, что есть в микс-именах. Я пытался сделать это, используя только Tidyverse, но не получилось. Я нашел решение, которое работает с использованием базы. Я знаю, что есть лучший способ, но я не могу понять это ...

library(tidyverse)
#> Warning: package 'ggplot2' was built under R version 3.6.1
#> Warning: package 'tidyr' was built under R version 3.6.1
#> Warning: package 'dplyr' was built under R version 3.6.1

#Acetometaphin 

synonyms <- c("Pediatrix","Percocet-5","Percocet-Demi","Perdolan Mono","Perfalgan", 
              "Phenaphen","Phenaphen W/Codeine","Phenipirin","Phogoglandin","Pinex", 
              "Piramin","Pirinasol","Plicet","Polmofen","Predimol","Predualito",
              "Prodol","Prontina","Puernol","Pulmofen", "Pyregesic-C")

mixNames <- c("Liquiprin","Midol Maximum Strength","Midol PM Night Time Formula",
              "Midol Regular Strength" ,"Midol Teen Formula","Naldegesic",
              "Ornex Severe Cold Formula","Percocet","Percogesic with Codeine",
              "Propacet" )

неудачная попытка:

#####STUFF THAT DIDNT WORK!!!!

# cross2(
#   .x = synonyms, .y = mixNames  #lists - each list has 2 lists - each of those is an atomic vector of 1
# ) %>% 
#   map_dfc(lift(str_detect)) #lift - modifies function to take a list of arguments - works for nested lists 

#this returns a df just like the apply 

# mix_syn_lgl_df <- map_dfc(
#   mixNames,
#   ~ map_lgl(synonyms, str_detect, pattern = .x)
# )

# colnames(mix_syn_lgl_df) <- mixNames
# 
# mix_syn_lgl_df$synonyms <- synonyms

Это действительно сработало:


#remove mixture names from synonyms

mix_syn_lgl_mat <- sapply(mixNames, function(x){
  str_detect(string = synonyms, pattern = x)
}) #returns a matrix 21x10 of logicals while preserving colnames

rownames(mix_syn_lgl_mat) <- synonyms #add synoyms as rownames
#create a new object with a new col of sum of TRUES in row
mix_syn_lgl_mat2 <- cbind(mix_syn_lgl_mat, rowSums(mix_syn_lgl_mat)) 
#take the numerical matrix mix_syn_lgl_mat2 and return the row names where the last col (rowsums) > 0
badNames <- row.names(mix_syn_lgl_mat2[mix_syn_lgl_mat2[, ncol(mix_syn_lgl_mat2)] > 0, ])
#filter out those names from the synonyms vector
pureSyn <- synonyms[!(synonyms %in% badNames)]

Создано в 2019-10-29 с помощью пакета Представление (v0.3.0)

Ответы [ 2 ]

1 голос
/ 29 октября 2019

Похоже, вам нужен вектор synonyms без значений, которые перекрываются с mixNames. Вы можете установить подмножество synonyms, чтобы удалить совпадения. Здесь str_c / paste сверните mixNames, чтобы создать шаблон со всеми mixNames. Затем вы просто используете частичное совпадение строк (то есть, str_detect и grepl оттуда).

Здесь используется stringr - что немного опрятно

synonyms[str_detect(synonyms, str_c(mixNames, collapse = "|"), negate = T)]

Или с использованием функций из базы R:

synonyms[!grepl(paste(mixNames, collapse = "|"), synonyms)]
# OR
grep(paste(mixNames, collapse = "|"), synonyms, value = T, invert = T)

В качестве примечания сайта, если выХотите проверить альтернативные способы сопоставления строк, посмотрите stringdist или другие функции / пакеты для расстояния между строками.

0 голосов
/ 29 октября 2019

Мне нравится создавать оператор %g% для подобных вещей. Следующее создает таблицу, содержащую значения из вашего кода, которые на самом деле работают :

library(tidyverse)

`%g%` <- function(x, y) {
  z <- paste0(y, collapse = "|")
  grepl(z, x, ignore.case = T)
}

tibble(syn = synonyms) %>% 
  filter(!syn %g% mixNames)
#> # A tibble: 19 x 1
#>    syn                
#>    <chr>              
#>  1 Pediatrix          
#>  2 Perdolan Mono      
#>  3 Perfalgan          
#>  4 Phenaphen          
#>  5 Phenaphen W/Codeine
#>  6 Phenipirin         
#>  7 Phogoglandin       
#>  8 Pinex              
#>  9 Piramin            
#> 10 Pirinasol          
#> 11 Plicet             
#> 12 Polmofen           
#> 13 Predimol           
#> 14 Predualito         
#> 15 Prodol             
#> 16 Prontina           
#> 17 Puernol            
#> 18 Pulmofen           
#> 19 Pyregesic-C

Аналогично, чтобы получить только те лекарства, которые в synonym соответствуют значению в mixNames:

tibble(syn = synonyms) %>% 
  filter(syn %g% mixNames)
#> # A tibble: 2 x 1
#>   syn          
#>   <chr>        
#> 1 Percocet-5   
#> 2 Percocet-Demi

Создано в 2019-10-29 пакетом представить (v0.3.0)

...