我有一个特定的清单:
lst <- list(A=c('aa', 'bb', 'cc'), B=c('ee', 'ff' ,'gg') ,C=c('aa', 'bb', 'bbc', 'dd'))
$A
[1] "aa" "bb" "cc"
$B
[1] "ee" "ff" "gg"
$C
[1] "aa" "bb" "bbc" "dd"
我str_extract_all
用来收集符合特定模式的部分数据。
> data <- str_extract_all(lst, 'bb') %>% unlist() %>% compact()
[1] "bb" "bb" "bb"
我想在一个小标题上显示结果,指示从中提取模式的源(即列表标题)。由于在 $C 中重复出现“bb”,这会产生以下错误。
> tibble(data = data, src = names(lst[grep('bb', lst)]))
錯誤: Column `src` must be length 1 or 3, not 2
当没有重复出现时,代码可以正常工作。
> lst <- list(A=c('aa', 'bb', 'cc'), B=c('ee', 'ff', 'gg') ,C=c('aa', 'bb', 'cc', 'dd'))
$A
[1] "aa" "bb" "cc"
$B
[1] "ee" "ff" "gg"
$C
[1] "aa" "bb" "cc" "dd"
> data <- str_extract_all(lst, 'bb') %>% unlist() %>% compact()
> tibble(data = data, src = names(lst[grep('bb', lst)]))
# A tibble: 2 x 2
data src
<chr> <chr>
1 bb A
2 bb C
如何编码以避免错误?
# A tibble: 2 x 2
data src
<chr> <chr>
1 bb A
2 bb C
3 bbc C
在研究我的解决方案时,我认为我的问题最终归结为:
> pattern <- c('bb', 'ee')
> grep(paste(pattern, collapse="|"), lst)
[1] 1 2 3
grep()
告诉我具体的字符串模式可以在我列表的第一项和第三项中找到。
我宁愿做的是在grep()
发现模式重复出现时重复项目编号。
[1] 1 2 3 3
我应该能够使用这种模式来生成一个源向量,并在以后cbind()
使用我的str_extract()
结果:
> rslt <- tibble(data = c('bb', 'ee', 'bb', 'bbc'), src = c( 'A', 'B', 'C', 'C'))
# A tibble: 4 x 2
data src
<chr> <chr>
1 bb A
2 ee B
3 bb C
4 bbc C
解决方案:
这是我自己解决问题的方法。
lst <- list(A=paste0('aa', str_dup("xy", 50), "bb", str_dup("ov", 50), "bb", str_dup("nm", 50), 'cc'), B=paste0('ee', 'ff' ,'gg') ,C=paste0('aa', str_dup("qed", 50), "bb", str_dup("sh", 50), 'bbc', 'dd'))
x <- str_count(lst, "bb") #Count instances to indicate repeats
x <- x[x != 0] #Remove the 0s
src.id <- mapply(rep, grep('bb', lst), x) %>% unlist() #Repeat source index to generate source vector
rslt <- tibble(str = str_extract_all(lst, "..bb..") %>% unlist() %>% compact(), src = names(lst[src.id]))
# A tibble: 4 x 2
str src
<chr> <chr>
1 xybbov A
2 ovbbnm A
3 edbbsh C
4 shbbcd C
即使重复的模式嵌入到子字符串中(如上),这也有效。