如何用R从KML属性表的长字符串中提取指定数值?
问题
我正在实现从互联网下载并提取KML数据的自动化流程,需要从长字符串属性中提取指定数值(如43.81 in),该数值位于“...Simulated Basin Snow Water Equivalent for Mar 04, 2023”之后。已通过以下R代码筛选出目标流域数据,但无法提取所需数值:
basins <- c('CARSON - CRSN CITY L (STWN2LLF)', 'CARSON - CRSN CITY L (STWN2LUF)', 'EF CARSON - GRDNVL L (GRDN2LLF)', 'EF CARSON - GRDNVL L (GRDN2LUF)', 'EF CARSON-MRKLEEVLLE (CEMC1HLF)', 'EF CARSON-MRKLEEVLLE (CEMC1HUF)', 'WF CARSON - WOODFRDS (WOOC1HOF)') date <- c('Mar_04_2023') url_upper <- paste('https://www.cnrfc.noaa.gov/archive/sweBasins/SWEbasinsVal_', date, ".kml", sep = "") kml_upper <- st_read(url_upper) kml_upper <- subset(kml_upper, kml_upper$Name %in% basins) kml_upper$geometry <- NULL head(kml_upper,3)
解决方案
方法1:使用stringr包(语法清晰,推荐)
利用stringr的str_extract结合正则表达式,精准定位目标数值:
library(stringr) # 假设长字符串存储在Description列,提取带单位的数值(如43.81 in) kml_upper$swe_value <- str_extract(kml_upper$Description, "(?<=Simulated Basin Snow Water Equivalent for [A-Z][a-z]{2} \\d{1,2}, \\d{4} )\\d+\\.\\d+ in") # 若只需纯数值,去掉单位并转为数字类型 kml_upper$swe_numeric <- as.numeric(str_extract(kml_upper$Description, "(?<=Simulated Basin Snow Water Equivalent for [A-Z][a-z]{2} \\d{1,2}, \\d{4} )\\d+\\.\\d+"))
正则说明:
(?<=...)正向断言,确保提取内容在指定文本之后[A-Z][a-z]{2} \\d{1,2}, \\d{4}匹配日期格式(如Mar 04, 2023)\\d+\\.\\d+ in匹配带小数点的数值加单位
方法2:使用base R原生函数
无需额外安装包,用regmatches和regexpr实现:
# 提取带单位的数值 pattern <- "(?<=Simulated Basin Snow Water Equivalent for [A-Z][a-z]{2} \\d{1,2}, \\d{4} )\\d+\\.\\d+ in" kml_upper$swe_value <- regmatches(kml_upper$Description, regexpr(pattern, kml_upper$Description, perl=TRUE)) # 提取纯数值并转为数字 pattern_numeric <- "(?<=Simulated Basin Snow Water Equivalent for [A-Z][a-z]{2} \\d{1,2}, \\d{4} )\\d+\\.\\d+" kml_upper$swe_numeric <- as.numeric(regmatches(kml_upper$Description, regexpr(pattern_numeric, kml_upper$Description, perl=TRUE)))
注意事项
- 如果长字符串不在
Description列,替换成实际列名 - 若日期格式有变动(如月份全称、数字格式),需调整正则中的日期匹配部分
- 可先执行
head(kml_upper$Description)查看字符串结构,再微调正则
内容的提问来源于stack exchange,提问作者Koda
相关产品推荐
相关产品推荐

