簡體   English   中英

在 R 中匹配具有多個模式的字符向量

[英]Matching a character vector with multiple patterns in R

我有兩個數據表。 第一個 data.table,DT_1,包含字符串和匹配類型如下:

library(data.table)  
DT_1 <- data.table(Source_name = c("Apple","Banana","Orange","Pear","Random"),
                   Match_type = c("Anywhere","Beginning","Anywhere","End","End"))

然后我想使用 DT_1 中指定的匹配類型將“Source_name”字符串的第一個匹配項從 DT_1 返回到 DT_2 的列名(如下所示)。 匹配將在不區分大小寫的情況下進行。

DT_2 <- data.table(Pear_1 = 1,Eat_apple = 1,Split_Banana = 1,
                   Pear_2 = 1,Eat_pear = 1,Orange_peel = 1,Banana_chair = 1)

例如,字符串“Apple”可以在 DT_2 的列名稱中的任何位置找到。 第一個例子是“Eat_apple”。

對於下一個字符串“Banana”,它必須在列名稱字符串的開頭匹配。 第一個例子是“Banana_chair”。

我寫了一些(非常丑陋的)代碼來處理這個問題,如下所示:

library(purrr)      
DT_1[,Col_Name := names(DT_2)[unlist(pmap(.l = .SD[,.(x = Match_type,y = Source_name)],
              .f = function(x,y){
                  if(x == "Anywhere"){
                       grep(tolower(y),tolower(names(DT_2)))[1] # returns the first match if there is a match anywhere
                  }else if (x == "Beginning"){
                       grep(paste0("^",tolower(y),"."),tolower(names(DT_2)))[1] # returns the first match if the string is at the beginning (denoted by the anchor "^")
                  }else if (x == "End"){
                        grep(paste0(".",tolower(y),"$"),tolower(names(DT_2)))[1] # returns the first match if the string is at the end (denoted by the end anchor "$")
                  }}))]]

我嘗試使用 stringr package 中的 string_extract / string_detect 來重現 output,但我對 DT_2 中的模式和列數有不同的長度這一事實並不滿意。

任何人都可以提供有關如何在這里改進我的代碼的任何提示嗎? 我不拘泥於某種特定的方法。

提前致謝, 菲爾

一種方法是先准備正則表達式,然后為每個Source_name找到第一個對應的匹配項。

library(dplyr)
library(purrr)
library(stringr)

cols <- names(DT_2)

DT_1 %>%
  mutate(regex = case_when(Match_type == "Anywhere" ~ Source_name, 
                           Match_type == "Beginning" ~ str_c('^',Source_name), 
                           Match_type == "End" ~str_c(Source_name, '$')), 
         Col_Name = map_chr(regex, 
                    ~str_subset(cols, regex(.x, ignore_case = TRUE))[1]))

#   Source_name Match_type   regex     Col_Name
#1:       Apple   Anywhere   Apple    Eat_apple
#2:      Banana  Beginning ^Banana Banana_chair
#3:      Orange   Anywhere  Orange  Orange_peel
#4:        Pear        End   Pear$     Eat_pear
#5:      Random        End Random$         <NA>

請注意, str_subset中的[1]在兩種情況下很有用

  1. 當存在多個匹配項時,它僅返回第一個匹配項。
  2. 當沒有匹配時,它返回NA

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM