R 以逗号分隔的文件,单元格中有多个逗号

R 以逗号分隔的文件,单元格中有多个逗号,r,R,对于一个研究项目,我们得到了一个大型SAP数据库转储文件作为CSV文件。分隔符是逗号(“,”)。 问题是有些列存储了一些文本。这把我的数据导入搞砸了。只有一列包含这些多个逗号 我已经尝试将整个文件作为字符串读取,然后使用str_split()拆分行。我认为更合适的方法是使用一些正则表达式 “常规”数据如下所示: 010,0040,0000399500,2018,KX,01/17/2015 00:00:00,01/17/2015 00:00:00,,ZAR,,2,,40,S,S,13860.00,

对于一个研究项目,我们得到了一个大型SAP数据库转储文件作为CSV文件。分隔符是逗号(“,”)。 问题是有些列存储了一些文本。这把我的数据导入搞砸了。只有一列包含这些多个逗号

我已经尝试将整个文件作为字符串读取,然后使用str_split()拆分行。我认为更合适的方法是使用一些正则表达式

“常规”数据如下所示:

010,0040,0000399500,2018,KX,01/17/2015 00:00:00,01/17/2015 00:00:00,,ZAR,,2,,40,S,S,13860.00,VOUCHERS 126,,1000,0004301410,,0000669010,,,,0.000,,,0,0.00,ZAR,VOUCHERS,20180117,,
“损坏”的数据记录如下所示。牢房、停车场、机票是一个牢房的内容,但将分为三个

010,0040,0000399500,2018,KX,01/17/2015 00:00:00,01/23/2015 00:00:00,,ZAR,,2,,40,S,S,482.46,CELL,PARKING,AIRFARE,,1000,0004300010,,0000682110,,,,0.000,,,0,0.00,ZAR,CELL PARKING,20180123,,
这里我的代码片段非常有限

mydata = read.delim("SAP_input_file.csv", sep = ",")

也许一些正则表达式可以帮上忙。然而,我的代码并不是泛化的,它适用于您的特定示例,有三个用逗号分隔的完整单词。但也许你可以扩展逻辑,使之适合你的数据:)


这里有两种选择

1)gsubfn使用结尾注释中的
输入
,假设每行有35个字段,其中第17个字段可能有问题。第17个字段中可以有任意数量的逗号,包括零。现在,使用捕获组(即括号)来围绕字段,创建与此类行匹配的模式。将gsubfn中的
read.pattern
与该模式一起使用以将其读入

library(gsubfn)
pat <- paste0("^", strrep("([^,]*),", 16), "(.*)", strrep(",([^,]*)", 18), "$")
read.pattern(text = input, pat = pat)
ss <- input
for(i in 1:16) ss <- sub(",", ";", ss)
for(i in 1:18) ss <- sub("(.*),", "\\1;", ss)
read.table(text = ss, sep = ";")
2)Base R此解决方案仅使用Base R。我们用分号替换前16个逗号,然后用分号替换后18个逗号。然后把它读进去

library(gsubfn)
pat <- paste0("^", strrep("([^,]*),", 16), "(.*)", strrep(",([^,]*)", 18), "$")
read.pattern(text = input, pat = pat)
ss <- input
for(i in 1:16) ss <- sub(",", ";", ss)
for(i in 1:18) ss <- sub("(.*),", "\\1;", ss)
read.table(text = ss, sep = ";")

ss什么单元格“损坏”有模式吗?文本中是否总是包含逗号的同一单元格?另外,为了确认,您无法重复数据库转储,以便它使用不同的分隔符或在每个单元格周围添加引用字符?@divibisan很遗憾,无法获得新转储。。。是的,它总是同一列,带有多个可能的逗号。多值列后面的单元格如何?它是否具有不同的数据类型或任何区别特征?读入并将这些值合并到一列并不困难,棘手的部分是确定每行中的哪些值被不正确地拆分(并且应该合并回多值列),哪些值是以下值,正确地拆分列您能给我们提供更多的示例行和更少的列吗?~10行中混合了损坏的单元格示例,比如说,损坏列前面有2列,后面有2列,这会让事情更清楚。
ss <- input
for(i in 1:16) ss <- sub(",", ";", ss)
for(i in 1:18) ss <- sub("(.*),", "\\1;", ss)
read.table(text = ss, sep = ";")
s1 <- "010,0040,0000399500,2018,KX,01/17/2015 00:00:00,01/17/2015 00:00:00,,ZAR,,2,,40,S,S,13860.00,VOUCHERS 126,,1000,0004301410,,0000669010,,,,0.000,,,0,0.00,ZAR,VOUCHERS,20180117,,"
s2 <- "010,0040,0000399500,2018,KX,01/17/2015 00:00:00,01/23/2015 00:00:00,,ZAR,,2,,40,S,S,482.46,CELL,PARKING,AIRFARE,,1000,0004300010,,0000682110,,,,0.000,,,0,0.00,ZAR,CELL PARKING,20180123,,"
input <- c(s1, s2)