我有这个数据帧,并且正在尝试提取一些数据,我实际上没有问题,但是我觉得应该有一个更好/更优雅的方法来实现它。
所以,我有这个字符串
CVEGEO=0901500011337<BR>CVE_ENT=09<BR>CVE_MUN=015<BR>CVE_LOC=0001<BR>CVE_AGEB=1337<BR>
136次,我对MUN=(.*) and AGEB=(.*)
感兴趣
要获取我使用的信息:
test1 <- sub(".*_MUN=(.*)<BR>CVE_LOC=0001<BR>CVE_AGEB=(.*)<.*", "\\1_\\2", L1_AGEB$description)
str_split_fixed(test1, "_", 2)
它工作得很好,但是,就像我说的那样,这只是出于学术/改进的目的?有没有一种简单/优雅的方法?
谢谢
答案 0 :(得分:1)
通过将输入转换为DCF格式,我们可以完全解析整个输入。这样做的好处是可以轻松地随后提取任何字段。
假设最后一个注解中显示的输入x
,我们可以用换行符替换<BR>
并用冒号替换=
,然后用read.dcf
读取剩下的内容。不使用任何软件包。
x2 <- gsub("=", ":", gsub("<BR>", "\n", x))
read.dcf(textConnection(x2))
给出此字符矩阵:
CVEGEO CVE_ENT CVE_MUN CVE_LOC CVE_AGEB
[1,] "0901500011337" "09" "015" "0001" "1337"
[2,] "0901500011337" "09" "015" "0001" "1337"
[3,] "0901500011337" "09" "015" "0001" "1337"
使用magrittr软件包的变化形式是:
library(magrittr)
x %>%
gsub("<BR>", "\n", .) %>%
gsub("=", ":", .) %>%
textConnection %>%
read.dcf
x <- "CVEGEO=0901500011337<BR>CVE_ENT=09<BR>CVE_MUN=015<BR>CVE_LOC=0001<BR>CVE_AGEB=1337<BR>"
x <- rep(x, 3)
答案 1 :(得分:0)
您可以对PCRE regex使用regmatches
/ regexpr
方法,该方法将在已知的“前缀”之后提取1个以上的数字:
x <- "CVEGEO=0901500011337<BR>CVE_ENT=09<BR>CVE_MUN=015<BR>CVE_LOC=0001<BR>CVE_AGEB=1337<BR>"
regmatches(x, regexpr("_MUN=\\K\\d+", x, perl=TRUE))
## => [1] "015"
regmatches(x, regexpr("_AGEB=\\K\\d+", x, perl=TRUE))
## => [1] "1337"
在线查看R demo。
正则表达式详细信息
_MUN=
-_MUN
文字\K
-匹配重置运算符,该运算符会丢弃到目前为止已匹配的文本\d+
-1个以上的数字。使用perl=TRUE
对于正则表达式的工作至关重要。
等效于stringr
:
library(stringr)
str_extract(x, "(?<=_MUN=)\\d+")
str_extract(x, "(?<=_AGEB=)\\d+")
后面的(?<=...)
正向外观仅检查当前位置左侧的模式匹配项,但不使用文本,即不将其放入匹配值。
第2列和第3列是一个花哨的解决方案,其中stringr::str_match
一目了然地捕获了结果。
library(stringr)
str_match(x, "_MUN=(\\d+).*_AGEB=(\\d+)")
# [,1] [,2] [,3]
# [1,] "_MUN=015<BR>CVE_LOC=0001<BR>CVE_AGEB=1337" "015" "1337"
答案 2 :(得分:0)
绝对看看rex
软件包,
它具有学习曲线,
但这很漂亮:
library(rex)
rex::re_matches("CVEGEO=0901500011337<BR>CVE_ENT=09<BR>CVE_MUN=015<BR>CVE_LOC=0001<BR>CVE_AGEB=1337<BR>",
pattern = rex::rex(
"MUN=",
capture(any_numbers, name = "MUN"),
anything,
"AGEB=",
capture(any_numbers, name = "AGEB")
))
MUN AGEB
1 015 1337
答案 3 :(得分:0)
This answer效率低下。在这里,也许,我们只使用[0-9]
而不是\d
,这在时间和空间复杂性方面的表现可能微不足道,我只是猜测,就像您提到的那样,当我们使用正则表达式时,原始表达式就很好,通常不建议环顾四周,也不建议使用其他任何奇特的方法。
MUN=([0-9]+).+AGEB=([0-9]+)
我很确定应该有其他方法来改进我们希望在此处完成的工作,但是关键是,您的原始表达已经在走正确的道路,但也许不是正确的道路,为此我们可能需要权衡所期望的优雅的原因。
请在评论中查看其他视图,我只是在参考,这里实际上没有任何意见/建议,即使听起来可能不是这样。