我正在尝试使用R.中的函数fread读取多个csv文件(如300(
当我在excel中打开其中一个csv文件时,即使某些观察结果包含逗号,列也会正确分隔。
当我尝试读取其中一个文件时,函数不会读取文件中的所有观察结果,下一个错误出现
> file_prueba<-fread("Datos/Datos_precios/INP_PP_CAB18 (7)_A_vivienda_06_2020.csv", skip = 5, header = TRUE)
Warning message:
In fread("Datos/Datos_precios/INP_PP_CAB18 (7)_A_vivienda_06_2020.csv", :
Stopped early on line 1073. Expected 17 fields but found 22. Consider fill=TRUE and comment.char=. First discarded non-empty line: <<"2020","06","20/07/2020 12:00:00 a. m.","12","San Luis Potosí, S.L.P.","3. Vivienda","3.1. Costo de uso de vivienda","3.1.1. Costo de uso de vivienda","42 Vivienda propia","140","Productos para reparación menor de la vivienda","001","PLOMERIA, TUBO DE PVC, REFORZADO, 4", PZA 6 MTS","231.55","1","PZA","">>
因此我无法阅读整个文件。我怀疑这是因为其中一个观察结果中包含了逗号,比如";PLOMERIA,TUBO DE COBRE,DE 60 MTS";。但我不确定。
如何在不逐个修复每个csv文件的情况下修复此问题?
这是我在示例中使用的文件,但正如我所说,我需要读取多个文件,如下所示:https://drive.google.com/file/d/1gSjyL14sZQC5KNtMXhN_iN79xCETTZAG/view?usp=sharing
文件有两种损坏方式:第1073行和第3401行嵌入了引号。但这里还有另一个问题。。。请参阅第二节fread
和双双引号以了解fread
的问题。
(最终,这是导出过程的失败,是fread
读取嵌入双引号的失败。(
损坏的线路
向右滚动查看问题。
-
第1073行:
"2020","06","20/07/2020 12:00:00 a. m.","12","San Luis Potosí, S.L.P.","3. Vivienda","3.1. Costo de uso de vivienda","3.1.1. Costo de uso de vivienda","42 Vivienda propia","140","Productos para reparación menor de la vivienda","001","PLOMERIA, TUBO DE PVC, REFORZADO, 4", PZA 6 MTS","231.55","1","PZA","" ---> ---> ---> ---> ---> ---> ---> ---> ---> ---> ---> ---> ---> ^-- this quote is incorrect
-
第3401行:
"2020","06","20/07/2020 12:00:00 a. m.","43","Campeche, Camp.","3. Vivienda","3.1. Costo de uso de vivienda","3.1.1. Costo de uso de vivienda","42 Vivienda propia","140","Productos para reparación menor de la vivienda","003","NACOBRE, PLOMERIA, TUBO DE COBRE, BARRA DE 1/2" X 6 MT","316.76","1","PZA","" ---> ---> ---> ---> ---> ---> ---> ---> ---> ---> ^-- this quote is incorrect
最好的解决方案是让任何人/流程导出该文件以导出符合CSV。
这里有一个命令行(sed
(修复程序,它将允许fread
在没有警告或错误的情况下加载它(这是在shell提示符上,而不是在R中(。
sed -i
-e 's/", PZA/"", PZA/g'
-e s'/BARRA DE 1/2"/BARRA DE 1/2""/g'
"INP_PP_CAB18 (7)_A_vivienda_06_2020.CSV"
简单解释:CSV标准(在https://en.wikipedia.org/wiki/Comma-separated_values)建议双引号永远不应出现在带引号的字段中,或者如果存在,则应将其加倍(如在""
中,在值的中间生成单个"
(。
在这种情况下,它会发现两个非常具体的失败文本,并添加第二个引号。
-i
表示在适当的位置进行更改;也许更具防御性的用途是使用sed -e 's/../../g' -e 's/../../g' < oldfile.csv > newfile.csv
,这将保留损坏的文件。交给你-e
添加了一个sed脚本/命令,可以给出多个命令- CCD_ 11表示用CCD_ 13中的字符串替换模式CCD_;CCD_ 14表示";全球">
这会更改两行(为了简单起见,这里一行接一行显示:
"2020","06","20/07/2020 12:00:00 a. m.","12","San Luis Potosí, S.L.P.","3. Vivienda","3.1. Costo de uso de vivienda","3.1.1. Costo de uso de vivienda","42 Vivienda propia","140","Productos para reparación menor de la vivienda","001","PLOMERIA, TUBO DE PVC, REFORZADO, 4"", PZA 6 MTS","231.55","1","PZA",""
"2020","06","20/07/2020 12:00:00 a. m.","43","Campeche, Camp.","3. Vivienda","3.1. Costo de uso de vivienda","3.1.1. Costo de uso de vivienda","42 Vivienda propia","140","Productos para reparación menor de la vivienda","003","NACOBRE, PLOMERIA, TUBO DE COBRE, BARRA DE 1/2"" X 6 MT","316.76","1","PZA",""
---> ---> ---> ---> ---> ---> ---> ---> ---> ---> ---> ---> ---> ^^^^^-- the changes, double-double quotes
仅供参考:如果路径中没有sed
。。。如果您运行的是windows,请查看RTools40路径;对我来说,我有c:/rtools40/usr/bin/sed.exe
。如果你在macos或linux上,找不到sed
,那么。。。这很奇怪。
在sed
命令正确执行之后,它将毫无问题地加载但是,不要让这误导你。。。它并不是真正固定的。继续阅读。
csv <- fread("INP_PP_CAB18 (7)_A_vivienda_06_2020.CSV", skip = 5)
csv
# Año Mes Fecha_Pub_DOF Clave ciudad Nombre ciudad División
# <int> <int> <char> <int> <char> <char>
# 1: 2020 6 20/07/2020 12:00:00 a. m. 1 Área Met. de la Cd. de México 3. Vivienda
# 2: 2020 6 20/07/2020 12:00:00 a. m. 1 Área Met. de la Cd. de México 3. Vivienda
# 3: 2020 6 20/07/2020 12:00:00 a. m. 1 Área Met. de la Cd. de México 3. Vivienda
...snip...
# 11 variables not shown: [Grupo <char>, Clase <char>, Subclase <char>, Clave genérico <int>, Genérico <char>, Consecutivo <int>, Especificación <char>, Precio promedio <num>, Cantidad <int>, Unidad <char>, ...]
fread
和双双引号
上面的问题是,虽然它看起来工作正常,但它(仍然(没有正确地嵌入引号。不幸的是,只要您希望您的数据具有所需的所有嵌入引号,那么就不能使用fread
。
为什么?
str(csv[1067,])
# Classes 'data.table' and 'data.frame': 1 obs. of 17 variables:
# $ Año : int 2020
# $ Mes : int 6
# $ Fecha_Pub_DOF : chr "20/07/2020 12:00:00 a. m."
# $ Clave ciudad : int 12
# $ Nombre ciudad : chr "San Luis Potosí, S.L.P."
# $ División : chr "3. Vivienda"
# $ Grupo : chr "3.1. Costo de uso de vivienda"
# $ Clase : chr "3.1.1. Costo de uso de vivienda"
# $ Subclase : chr "42 Vivienda propia"
# $ Clave genérico : int 140
# $ Genérico : chr "Productos para reparación menor de la vivienda"
# $ Consecutivo : int 1
# $ Especificación : chr "PLOMERIA, TUBO DE PVC, REFORZADO, 4"", PZA 6 MTS"
# $ Precio promedio: num 232
# $ Cantidad : int 1
# $ Unidad : chr "PZA"
# $ Estatus : chr ""
# - attr(*, ".internal.selfref")=<externalptr>
即,参见
csv$Especificación[1067]
# [1] "PLOMERIA, TUBO DE PVC, REFORZADO, 4"", PZA 6 MTS"
^^^^ should only be a single "
幸运的是,read.csv
在这里运行良好:
csv <- read.csv("INP_PP_CAB18 (7)_A_vivienda_06_2020.CSV", skip = 5)
csv$Especificación[1067]
# [1] "PLOMERIA, TUBO DE PVC, REFORZADO, 4", PZA 6 MTS"
仅供参考,如果您不关心嵌入的引号,那么如果您更改sed
表达式以删除双引号而不是将双引号加倍,则仍然可以使用fread
。即-e 's/", PZA/, PZA/g'
,对于第二表达式也是如此。我不建议首先这样做,因为它会改变你的数据,而你不应该这样做
您链接的文件已正确引用。它有5行非CSV数据,所以跳过这些:
csv = read.csv("INP_PP_CAB18 (7)_A_vivienda_06_2020.CSV", header = T, skip = 5, fileEncoding = "Latin1")
这对我来说很好。我对fread
不太熟悉,而且这个文件似乎确实有问题。你需要data.table::fread
有什么原因吗?