R语言物种编码生成优化:替代str_match与正则整合问询
解决方案:简化物种编码生成流程
问题(a):stringr中替代str_match的简化方案
当然有,str_extract + 字符串拼接或者str_replace配合匿名函数都能比str_match更简洁地完成提取与拼接,避免处理str_match返回的矩阵。
方案1:分步骤提取后拼接
先分别提取属名前4字符、种名部分(处理spp.→sp.后取前3),再直接拼接:
library(stringr) # 示例数据 df <- tibble::tibble( species = c("Quercus robur", "Pinus sylvestris", "Acer sp.", "Fagus spp.", "Salix alba var. vitellina") ) # 提取属名前4字符 genus_part <- str_extract(df$species, "^\\w{4}") # 提取种名部分、替换spp.为sp.、截取前3字符 species_part <- df$species %>% str_extract("(?<=\\s)(spp\\.|sp\\.|\\w+)") %>% str_replace("spp\\.", "sp\\.") %>% str_sub(1, 3) # 拼接生成编码 df$species_code <- str_c(genus_part, species_part)
方案2:一步用str_replace回调函数
利用str_replace的正则捕获组和匿名函数,在单次调用中完成所有逻辑:
df$species_code <- str_replace(df$species, "^(\\w{4})\\s+(spp\\.|sp\\.|(\\w+))", function(match) { # 处理种名部分:替换spp.为sp.,截取前3字符 sp_segment <- ifelse(match[2] == "spp.", "sp.", ifelse(match[2] == "sp.", "sp.", str_sub(match[3], 1, 3))) # 拼接属名和处理后的种名 str_c(match[1], sp_segment) })
问题(b):将spp.→sp.整合进正则逻辑
完全可以,有两种思路:
- 正则捕获组分支匹配:在匹配种名部分时,同时匹配
spp.和sp.,在回调函数中统一替换为sp. - 先正则替换
spp.再处理截取:用str_replace先把所有spp.替换为sp.,再执行提取拼接
整合后的正则示例(方案1)
df$species_code <- str_replace(df$species, # 正则捕获:属名前4字符 + 种名部分(含sp./spp./正常种名) "^(\\w{4})\\s+(?:spp\\.|sp\\.|(\\w+))", function(m) { # 种名部分处理:若匹配到spp./sp.则用sp.,否则取前3字符 sp_part <- case_when( grepl("spp\\.|sp\\.", m[2]) ~ "sp.", TRUE ~ str_sub(m[2], 1, 3) ) str_c(m[1], sp_part) })
整合后的正则示例(方案2)
df$species_code <- df$species %>% # 先统一替换spp.为sp. str_replace("\\s+spp\\.", " sp.") %>% # 提取属名前4 + 种名前3拼接 str_replace("^(\\w{4})\\s+(\\w{1,3}).*", "\\1\\2")
示例结果
处理后的数据框如下:
| species | species_code |
|---|---|
| Quercus robur | Querrob |
| Pinus sylvestris | Pinsyl |
| Acer sp. | Acersp. |
| Fagus spp. | Fagusp. |
| Salix alba var. vitellina | Salialb |
内容的提问来源于stack exchange,提问作者Stefan
相关产品推荐
相关产品推荐

