读取R中带有逗号的csv-flie,停止fread功能



我正在尝试使用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有什么原因吗?

最新更新