LeG*_*sII 1 regex r gsub data.table
由于我的csv文件已损坏,因此我使用以下命令将其读入R:
dataDT <- data.table::fread(".../test.csv", sep = NULL)
Run Code Online (Sandbox Code Playgroud)
它为数据集提供了类似的内容:
dataDT <- data.table("ColA,ColB,ColC,ColD" = c("1,10,some text... , some text,,20190801",
"2,22,some text... , some text,,20190801",
"3,30,some text... , some text,,20170601"))
dataDT
> dataDT
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
Run Code Online (Sandbox Code Playgroud)
现在,我想要将每行中的字符串分成4个新列:
targetDT <- data.table(ColA = c(1,2,3),
ColB = c(10,22,30),
ColC = c("some text... , some text,", "some text... , some text,", "some text... , some text,"),
ColD = c("20190801","20190801",'20170601'))
targetDT
> targetDT
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
Run Code Online (Sandbox Code Playgroud)
逻辑将是:
如何实现以上逻辑?
编辑_1:
敏感数据,抱歉,我无法提供确切数据。看起来像:
ID,Code1,Project_Name,Report_Date
1: 123123,1, A & B,20100101
2: 1413,2, C, D and E,20120101
3: 53163,333, F, G,20140303
4: 23453,44,This is a name,20160801
5: 12645,555,5th test, to continue,20190501
Run Code Online (Sandbox Code Playgroud)
因此,第一个逗号之前的所有内容绝对是数字,第一和第二个逗号之间的所有内容也都是数字。上一个逗号之后的所有内容绝对是类似日期的8位数字。中间部分可以包含多个逗号,但不能包含引号(这是fread将逗号视为定界符的原因)。
这是一种regex模式,使您可以替换与前导2和终极数字值相邻的逗号字符,并将它们彼此分隔,并用空格分隔周围的文本。使用非空格字符进行分隔可能更安全,因为我的下一步将是使用其中一个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"
Run Code Online (Sandbox Code Playgroud)
模式中的括号用于创建“捕获类”,在每种情况下,我都使用“ \ 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
Run Code Online (Sandbox Code Playgroud)
注意:如果您的数字值包含逗号或前导或尾随货币,则您需要更改示例,因为"\\d"用于捕获数字字符组将不再成功。