regexp R-提取逗号之间的字符串
由于我的csv文件已损坏,我正在使用以下命令将其读入R:regexp R-提取逗号之间的字符串,r,regex,data.table,gsub,R,Regex,Data.table,Gsub,由于我的csv文件已损坏,我正在使用以下命令将其读入R: dataDT <- data.table::fread(".../test.csv", sep = NULL) 所以,第一个逗号之前的所有内容都是数字,第一个和第二个逗号之间的所有内容都是数字。最后一个逗号之后的所有内容都绝对是一个类似于8位数字的日期。中间部分可以包含多个逗号,但不包含引号(我想这就是fread将逗号视为分隔符的原因).这里有一个regex模式,允许您替换与前导两个和终端数值相邻的逗号字符,并用空格将它们彼此和周
dataDT <- data.table::fread(".../test.csv", sep = NULL)
所以,第一个逗号之前的所有内容都是数字,第一个和第二个逗号之间的所有内容都是数字。最后一个逗号之后的所有内容都绝对是一个类似于8位数字的日期。中间部分可以包含多个逗号,但不包含引号(我想这就是fread将逗号视为分隔符的原因).这里有一个
regex
模式,允许您替换与前导两个和终端数值相邻的逗号字符,并用空格将它们彼此和周围的文本分隔开。使用非空格字符分隔可能更安全,因为我的下一步是使用read.*
函数之一或fread
再次读取这些“行”。也许用“|”作为分隔符
sub("(\\d+)[,](\\d+)[,](.+)[,](\\d+)$",
"\\1 \\2 '\\3' \\4",
dataDT$"ColA,ColB,ColC,ColD" )
[1] "1 10 'some text... , some text,' 20190801" "2 22 'some text... , some text,' 20190801"
[3] "3 30 'some text... , some text,' 20170601"
模式中的括号用于创建“捕获类”,在每种情况下,我都使用“\d+”模式“捕获”了任意数量的数字或十进制分隔符。我还在替换模式中用单引号将文本(用“+”)括起来,这样第三列中的“内部空间”就不会被理解为分隔符。“\\1”
,“\\2”
等是对每个捕获类中捕获的字符的引用,按其在模式中的出现顺序排列。请参见?regex
。但是,如果使用不同的分隔符,则不需要单引号
下面是一个使用“|”作为sep
的测试
fread(text =sub("(\\d+)[,](\\d+)[,](.+)[,](\\d+)", "\\1|\\2|'\\3'|\\4", dataDT$"ColA,ColB,ColC,ColD" ) ,sep="|")
V1 V2 V3 V4
1: 1 10 'some text... , some text,' 20190801
2: 2 22 'some text... , some text,' 20190801
3: 3 30 'some text... , some text,' 20170601
注意:如果您的数值带有逗号或前导或尾随货币,则需要更改示例,因为使用了
“\\d”
捕获字符的数字组将不再成功。这里有一个regex
模式,允许您替换与前导两个和终端数值相邻的逗号字符,并用空格将它们彼此和周围的文本分隔开。使用非空格字符分隔可能更安全,因为我的下一步是使用read.*
函数之一或fread
再次读取这些“行”。也许用“|”作为分隔符
sub("(\\d+)[,](\\d+)[,](.+)[,](\\d+)$",
"\\1 \\2 '\\3' \\4",
dataDT$"ColA,ColB,ColC,ColD" )
[1] "1 10 'some text... , some text,' 20190801" "2 22 'some text... , some text,' 20190801"
[3] "3 30 'some text... , some text,' 20170601"
模式中的括号用于创建“捕获类”,在每种情况下,我都使用“\d+”模式“捕获”了任意数量的数字或十进制分隔符。我还在替换模式中用单引号将文本(用“+”)括起来,这样第三列中的“内部空间”就不会被理解为分隔符。“\\1”
,“\\2”
等是对每个捕获类中捕获的字符的引用,按其在模式中的出现顺序排列。请参见?regex
。但是,如果使用不同的分隔符,则不需要单引号
下面是一个使用“|”作为sep
的测试
fread(text =sub("(\\d+)[,](\\d+)[,](.+)[,](\\d+)", "\\1|\\2|'\\3'|\\4", dataDT$"ColA,ColB,ColC,ColD" ) ,sep="|")
V1 V2 V3 V4
1: 1 10 'some text... , some text,' 20190801
2: 2 22 'some text... , some text,' 20190801
3: 3 30 'some text... , some text,' 20170601
注意:如果数值带有逗号或前导或尾随货币,则需要更改示例,因为使用
“\\d”
捕获数字字符组将不再成功。使用stringr的解决方案
库(data.table)
图书馆(stringr)
图书馆(dplyr)
dataDT%
选择(可乐、可乐、可乐、冷)
数据传输
#>感冒
#>1 10一些文本,一些文本,20190801
#>2 22一些文本,一些文本,20190801
#>3 30一些文字,一些文本,20170601
于2019-06-27由(v0.3.0)使用stringr的解决方案创建
库(data.table)
图书馆(stringr)
图书馆(dplyr)
dataDT%
选择(可乐、可乐、可乐、冷)
数据传输
#>感冒
#>1 10一些文本,一些文本,20190801
#>2 22一些文本,一些文本,20190801
#>3 30一些文字,一些文本,20170601
由(v0.3.0)创建于2019-06-27。目前发布的答案建议使用正则表达式解决方案 或者,可以考虑立柱的位置。正如OP所指出的那样
- ColA在第一个逗号前有字符串李>
- ColB拥有第一个和第二个逗号之间的所有内容李>
- ColD在最后一个逗号后有字符串李>
- COLC在中间部分有字符串(它可能包含附加逗号)。
fread()
和sep=“,”
读取文件,这会导致数据集不对齐。在重新调整为长格式后,可以识别每行的第一列、第二列和最后一列以及中间列。可以为这些条目指定相应的列名。在最终重塑为宽格式的过程中,中间列折叠为ColC
library(data.table)
# read file
DT <- fread("
1,10,some text... some text,,20190801
2,22,some text... , some text,,20190801
3,30,some text... ,, some text,,20170601"
, sep = ","
, fill = TRUE
, header = FALSE
, strip.white = FALSE)
如果我们看中间结果,可以更好地解释这种方法
在melt()
之后,long
是
由此创建查找表lut
更新后,在重新整形为宽格式之前加入
现在,数据项已与其各自的列名对齐。到目前为止发布的答案建议使用正则表达式解决方案 或者,可以考虑立柱的位置。正如OP所指出的那样
- ColA在第一个逗号前有字符串李>
- ColB拥有第一个和第二个逗号之间的所有内容李>
- ColD在最后一个逗号后有字符串李>
- COLC在中间部分有字符串(它可能包含附加逗号)。
fread()
和sep=“,”
读取文件,这会导致数据集不对齐。在重新调整为长格式后,可以识别每行的第一列、第二列和最后一列以及中间列。可以为这些条目指定相应的列名。在t
library(data.table)
# read file
DT <- fread("
1,10,some text... some text,,20190801
2,22,some text... , some text,,20190801
3,30,some text... ,, some text,,20170601"
, sep = ","
, fill = TRUE
, header = FALSE
, strip.white = FALSE)
DT
V1 V2 V3 V4 V5 V6 V7
1: 1 10 some text... some text 20190801 NA NA
2: 2 22 some text... some text 20190801 NA
3: 3 30 some text... some text NA 20170601
cols <- c("ColA", "ColB", "ColC", "ColD")
# reshape from wide to long format
long <- melt(DT[, rn := .I], "rn", na.rm = TRUE)
# create lookup table to rename column names
lut <- long[, .(variable, col = rep(cols, c(1L, 1L, .N - 3, 1L))), by = rn]
# rename columns by an update join
long[lut, on = .(rn, variable), variable := col][]
# reshape and collapse
dcast(long, rn ~ variable, paste, collapse = ",")
ColA ColB ColC ColD
1: 1 10 some text... some text, 20190801
2: 2 22 some text... , some text, 20190801
3: 3 30 some text... ,, some text 20170601
rn variable value
1: 1 V1 1
2: 2 V1 2
3: 3 V1 3
4: 1 V2 10
5: 2 V2 22
6: 3 V2 30
7: 1 V3 some text... some text
8: 2 V3 some text...
9: 3 V3 some text...
10: 1 V4
11: 2 V4 some text
12: 3 V4
13: 1 V5 20190801
14: 2 V5
15: 3 V5 some text
16: 2 V6 20190801
17: 3 V7 20170601
rn variable col
1: 1 V1 ColA
2: 1 V2 ColB
3: 1 V3 ColC
4: 1 V4 ColC
5: 1 V5 ColD
6: 2 V1 ColA
7: 2 V2 ColB
8: 2 V3 ColC
9: 2 V4 ColC
10: 2 V5 ColC
11: 2 V6 ColD
12: 3 V1 ColA
13: 3 V2 ColB
14: 3 V3 ColC
15: 3 V4 ColC
16: 3 V5 ColC
17: 3 V7 ColD
rn variable value
1: 1 ColA 1
2: 2 ColA 2
3: 3 ColA 3
4: 1 ColB 10
5: 2 ColB 22
6: 3 ColB 30
7: 1 ColC some text... some text
8: 2 ColC some text...
9: 3 ColC some text...
10: 1 ColC
11: 2 ColC some text
12: 3 ColC
13: 1 ColD 20190801
14: 2 ColC
15: 3 ColC some text
16: 2 ColD 20190801
17: 3 ColD 20170601