在 R 中的多个位置查找字符的匹配项

Finding matches on a character in more than one position in R

我有一个字符向量,我想在其中匹配第一部分和最后一部分,以便生成匹配字符列表。

这是一个示例字符:"20190625_165055_0f4e" 第一部分是日期。最后 4 个字符是唯一标识符。我需要列表中这两部分重复的所有字符。

我可以使用一个简单的正则表达式来根据位置匹配字符,但有些中间字符比其他字符多,例如"20190813_170215_17_1057"

这是一个示例向量:

mylist<-c("20190712_164755_1034","20190712_164756_1034","20190712_164757_1034","20190719_164712_1001","20190719_164713_1001","20190722_153110_1054","20190813_170215_17_1057","20190813_170217_22_1057","20190828_170318_14_1065")

这是所需的输出:

c("20190712_164755_1034","20190712_164756_1034","20190712_164757_1034")
c("20190719_164712_1001","20190719_164713_1001")
c("20190722_153110_1054")
c("20190813_170215_17_1057","20190813_170217_22_1057")
c("20190828_170318_14_1065")

编辑:使我的字符向量更简单并添加了所需的输出

我们可以去掉中间的子串 subsplit 然后根据 list 变成 list of character vector s

lst1 <- split(mylist, sub("^(\d+)_.*_([^_]+)$", "\1_\2", mylist))
lst1
#$`20190712_1034`
#[1] "20190712_164755_1034" "20190712_164756_1034" "20190712_164757_1034"

#$`20190719_1001`
#[1] "20190719_164712_1001" "20190719_164713_1001"

#$`20190722_1054`
#[1] "20190722_153110_1054"

#$`20190813_1057`
#[1] "20190813_170215_17_1057" "20190813_170217_22_1057"

#$`20190828_1065`
#[1] "20190828_170318_14_1065"

sub中,我们从字符串的开头(^)捕获((...))一个或多个数字(\d+),然后是_, 和其他字符 (.*) 直到 _ 并捕获其余不是 _ ([^_]+) 的字符直到结束 ( $) 的字符串。在 replacement 中,我们指定捕获组的反向引用(\1\2))。本质上,删除中间的变化部分并保留开头和结尾的固定子字符串并使用它来拆分字符向量

这是 tidyrextract 的替代方法。

library(tidyr)
result <- as.data.frame(mylist) %>%
  extract(1, into = c("date","var1","var2"),
          regex = "(^[0-9]{8}_[0-9]{6})_?(.*)?_([^_]+$)",
          remove = FALSE)
result
#                    mylist            date var1 var2
#1     20190625_165055_0f4e 20190625_165055      0f4e
#2     20190625_165056_0f4e 20190625_165056      0f4e
#3     20190625_165057_0f4e 20190625_165057      0f4e
#4     20190712_164755_1034 20190712_164755      1034
#...
#27 20190828_170318_14_1065 20190828_170318   14 1065
#28 20190828_170320_26_1065 20190828_170320   26 1065
#...

现在您可以根据这些变量轻松操作数据。

split(result,result$var2)
#$`0f22`
#                 mylist            date var1 var2
#29 20190917_165157_0f22 20190917_165157      0f22
#
#$`0f2a`
#                 mylist            date var1 var2
#18 20190813_152856_0f2a 20190813_152856      0f2a
#19 20190813_152857_0f2a 20190813_152857      0f2a
#...

我们可以使用 extract 将日期部分和最后 4 个字符提取到单独的列中。然后,我们使用 group_split 根据这两列拆分数据。

tibble::tibble(mylist) %>%
   tidyr::extract(mylist, c('col1', 'col2'), regex = '(.*?)_.*_(.*)', 
                  remove = FALSE) %>%
   dplyr::group_split(col1, col2, .keep = FALSE)


#[[1]]
# A tibble: 3 x 1
#  mylist              
#  <chr>               
#1 20190712_164755_1034
#2 20190712_164756_1034
#3 20190712_164757_1034

#[[2]]
# A tibble: 2 x 1
#  mylist              
#  <chr>               
#1 20190719_164712_1001
#2 20190719_164713_1001

#[[3]]
# A tibble: 1 x 1
#  mylist              
#  <chr>               
#1 20190722_153110_1054
#...