我正在尝试使用R中的正则表达式将字符串向量分解为多个变量,最好使用tidyr :: extract命令以dplyr-tidyr方式.对于矢量波纹中的不确定性:
sasdic <- data.frame(a=c(
'@1 ANO_CENSO 5. /*Ano do Censo*/',
'@71 TP_SEXO $Char1. /*Sexo*/',
'@72 TP_COR_RACA $Char1. /*Cor/raça*/',
'@74 FK_COD_PAIS_ORIGEM 4. /*Código País de origem*/' ))
Run Code Online (Sandbox Code Playgroud)
我想:
这将是结果
d <- data.frame(int_pos=c(1,72,72,74),
var_name=c('ANO_CENSO','TP_SEXO','TP_COR_RACA','FK_COD_PAIS_ORIGEM'),
x=c('5','Chart1','$Char1','4'),
label=c('Ano do Censo','Sexo','Cor/raça','Código País de origem') )
Run Code Online (Sandbox Code Playgroud)
我试着为此构建一个正则表达式.这是我到目前为止所得到的:
sasdic %>% extract(a, c('int_pos','var_name','x','label'),
"([0-9]+)([a-zA-Z_]+)([0-9]+|$Char[0-9]+)(something to get the label")
-> d
Run Code Online (Sandbox Code Playgroud)
正则表达式之上是不完整的.另外,我不知道如何在extract命令语法中明确表示要恢复的部分是什么以及要省略哪些部分.
在使用的正则表达式中,我们匹配更多标点字符([[:punct:]]+),即@接着捕获数字部分((\\d+)- 这将是我们感兴趣的第一列),接着是一个或多个空格(\\s+),然后是第二个捕获组(\\S+-一个或多个非空白字符即"ANO_CENSO"的第一行),其次是空间(\\s+),那么我们捕获第三组(([[:alum:]$]+)-即一个或多个字符,其包括具有沿着所述字母数字$,以便匹配$Char1),接下来我们匹配一个或多个不是字母的字符([^A-Za-z]+- 这应该摆脱空间和*),最后一部分我们捕获一个或多个不是*(([^*]+).
sasdic %>%
extract(a, into=c('int_pos', 'var_name', 'x', 'label'),
"[[:punct:]](\\d+)\\s+(\\S+)\\s+([[:alnum:]$]+)[^A-Za-z]+([^*]+)")
# int_pos var_name x label
#1 1 ANO_CENSO 5 Ano do Censo
#2 71 TP_SEXO $Char1 Sexo
#3 72 TP_COR_RACA $Char1 Cor/raça
#4 74 FK_COD_PAIS_ORIGEM 4 Código País de origem
Run Code Online (Sandbox Code Playgroud)
这是另一种选择,虽然它使用data.table包而不是tidyr:
library(data.table)
setDT(sasdic)
# split label
sasdic[, c("V1","label") := tstrsplit(a, "/\\*|\\*/")]
# remove leading "@", split remaining parts
sasdic[, c("int_pos","var_name","x") := tstrsplit(gsub("^@","",V1)," +")]
# remove unneeded columns
sasdic[, c("a","V1") := NULL]
sasdic
# label int_pos var_name x
# 1: Ano do Censo 1 ANO_CENSO 5.
# 2: Sexo 71 TP_SEXO $Char1.
# 3: Cor/raça 72 TP_COR_RACA $Char1.
# 4: Código País de origem 74 FK_COD_PAIS_ORIGEM 4.
Run Code Online (Sandbox Code Playgroud)
这假定"剩余部分"(除标签外)是空间分隔的.
这也可以在一个块中完成(这就是我要做的):
sasdic[, c("a","label","int_pos","var_name","x") := {
x = tstrsplit(a, "/\\*|\\*/")
x1s = tstrsplit(gsub("^@","",x[[1]])," +")
c(list(NULL), x1s, x[2])
}]
Run Code Online (Sandbox Code Playgroud)