如何在 R 中解析复杂的 csv 文件?

Posted

技术标签:

【中文标题】如何在 R 中解析复杂的 csv 文件?【英文标题】:How to parse a complicated csv file in R? 【发布时间】:2019-10-17 11:32:33 【问题描述】:

我一直在努力解析一个复杂的 *.csv 文件,如下所示。它有 6 行,但是,所有列标题、ID、字段值都列在用逗号分隔的单行中。大多数标题都有空格和单位“(in)”,需要按原样使用。

示例文件:

    Version,1.1,1198    
    Dimension Unit,in,1000.000000
    Angle Unit,°,17.095780
    Measurement Names,Body height (in),Head height (in),Neck height (mm),Distance neck to buttock (in),Distance neck-knee (in)
    Measurement IDs,0010,0020,0030,0040,0050
    C:\Data\new.csv,796,,398,212

我想要的是:

    跳过前 3 行 用标题制作 3 列: “测量名称”(取自第 4 行), “测量 ID”(取自第 5 行)和 “C:\Data\new.csv”(最后一行) 用逗号分隔所有字段并将它们转置到右列中 处理一些空字段值

正确解析后应该是这样排列的:

    Measurement Names             Measurement IDs  C:\Data\new.csv 
    Body height (in)              0010             796  
    Head height (in)              0020
    Neck height (in)              0030             398
    Distance neck to buttock (in) 0040             212
    Distance neck-knee (in)       0050                  

我尝试过 read.csv、read.table 但唯一成功读取的是 readLines。但是,即使给出了这个选项,它也没有跳过前 3 行。此外,什么编码也没关系。 假设

data <- "C:\\Temp\\test.csv"
filename <- file(data,open="r")

Zeile <-readLines(filename,
                  skip=3,
                  #warn=FALSE,
                  encoding = 'utf-16-be'
                  )
Zeile <- strsplit(Zeile, ",") # here I try to split 
for (i in 1:length(Zeile))
  print(Zeile[i])

close(filename)

结果如下所示:

[[1]]
[1] "Version" "1.1"     "1198\t"  

[[1]]
[1] "Length Unit" "mm"          "1000.000000"

[[1]]
[1] "Angle Unit" "°"         "57.295780" 

[[1]]
[1] "Measurement Names"             "Body height (mm)"              "Head height (mm)"             
[4] "Neck height (mm)"              "Distance neck to buttock (mm)" "Distance neck-knee (mm)"      

[[1]]
[1] "Measurement IDs" "0010"            "0020"            "0030"            "0040"           
[6] "0050"           

[[1]]
[1] "C:\\Data\\new.csv" "796"               ""                  "398"               "212"              

[[1]]
character(0)

有引号,并且字段值未在正确的列下对齐。

如何将预期结果放入数据框中以进行进一步处理?

【问题讨论】:

【参考方案1】:

你可以试试这个:

library(tidyverse)
read.csv("path/your_file.csv", sep = ",", skip = 3, colClasses = "character") %>% 
   gather(Measurement_Names, v, -Measurement.Names) %>% 
   spread(Measurement.Names, v)
             Measurement_Names  C:\\Data\\new.csv Measurement IDs
1              Body.height..mm.               796            0010
2       Distance.neck.knee..mm.                              0050
3 Distance.neck.to.buttock..mm.               212            0040
4              Head.height..mm.                              0020
5              Neck.height..mm.               398            0030

【讨论】:

为了完整起见,使用库tidyr @R.S.只是忘记包含所需的软件包。谢谢 感谢它的魅力。 %>% 在该代码中做了什么?【参考方案2】:

它不是 R,但我认为它可能有用。我正在使用 Miller (https://github.com/johnkerl/miller) 和 csvtk (https://bioinf.shenwei.me/csvtk/)。

跑步

tail -n +4 input_01.csv | mlr --nidx --fs "," cat -n  then unsparsify | csvtk transpose | tail -n +2

你会有

Measurement Names,Measurement IDs,C:\Data\new.csv
Body height (mm),0010,796
Head height (mm),0020,
Neck height (mm),0030,398
Distance neck to buttock (mm),0040,212
Distance neck-knee (mm),0050,

或者漂亮的打印运行

tail -n +4 input_01.csv | mlr --nidx --fs "," cat -n  then unsparsify | csvtk transpose | tail -n +2 | mlr --c2p cat

拥有

Measurement Names             Measurement IDs C:\Data\new.csv
Body height (mm)              0010            796
Head height (mm)              0020            -
Neck height (mm)              0030            398
Distance neck to buttock (mm) 0040            212
Distance neck-knee (mm)       0050            -

【讨论】:

以上是关于如何在 R 中解析复杂的 csv 文件?的主要内容,如果未能解决你的问题,请参考以下文章

如何从字符向量中解析 CSV 数据以提取数据框?

如何在 PHP 中解析 CSV 文件

如何在php中上传和解析CSV文件

如何在 R 中导入 CSV 文件? [关闭]

如何在 Bash 中解析 CSV 文件?

使用PHP在短时间内解析大型CSV文件