Могу ли я сделать этот поиск векторного текста в R без для l oop? - PullRequest
1 голос
/ 21 апреля 2020

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

set.seed(123)
library(tidyverse)

id <- paste0("V", sample((1000:9999), size = 5))
text <- c("ARROW", "ARROWHEAD", "OTHERARROW", "OTHER", "HEADOTHER")

df <- tibble(id, text)
df

  id    text      
  <chr> <chr>     
1 V3588 ARROW     
2 V8093 ARROWHEAD 
3 V4679 OTHERARROW
4 V8944 OTHER     
5 V9460 HEADOTHER 

Другой ищет эти клавиши и присваивает им более короткие значения:

original <- c("ARROW", "HEAD", "OTHER")
revised <- c("A", "H", "O")

lookup <- tibble(original, revised)
lookup

  original revised
  <chr>    <chr>  
1 ARROW    A      
2 HEAD     H      
3 OTHER    O  

Мой желаемый вывод - сделать df1, фрейм данных, который заменяет text комбинацией кодов revised:

correctText <- c("A", "AH", "AO", "O", "HO")

df1 <- tibble(id, correctText)
df1

  id    correctText
  <chr> <chr>      
1 V3588 A          
2 V8093 AH         
3 V4679 AO         
4 V8944 O          
5 V9460 HO  

Каков самый эффективный способ сделать это (только для базового R или dplyr) )? Сейчас я делаю это с for l oop, но это слишком медленно для приложения Shiny, где я хочу его реализовать.

Ответы [ 2 ]

1 голос
/ 21 апреля 2020

Только с базой R (и dplyr, так как вы используете тиббл, поэтому я также добавил mutate), вы можете использовать эту функцию:

multisub <- function(target, output, string) {
  replacement.list <- apply(cbind(target, output), 1, as.list)
  mygsub <- function(l, x) gsub(pattern = l[1], replacement = l[2], x, perl=TRUE)
  Reduce(mygsub, replacement.list, init = string, right = TRUE)
}

df %>% mutate(text = multisub(original, revised, text))
#> # A tibble: 5 x 2
#>   id    text 
#>   <chr> <chr>
#> 1 V3462 A    
#> 2 V3510 AH   
#> 3 V9717 OA   
#> 4 V3985 O    
#> 5 V2841 HO

# base R oly:
data.frame(id=id, text = multisub(original, revised, text), stringsAsFactors = FALSE)

С точки зрения производительности это довольно конкурентоспособен с решением stringr.

1 голос
/ 21 апреля 2020

Мы можем использовать str_replace с named вектором

library(dplyr)
library(stringr)
df %>%
    mutate(text = str_replace_all(text, set_names(revised, original)))
# A tibble: 5 x 2
#  id    text 
#  <chr> <chr>
#1 V3462 A    
#2 V3510 AH   
#3 V9717 OA   
#4 V3985 O    
#5 V2841 HO   

stringr функции основаны на stringi и должны быть очень эффективными

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...