如何正确导入以分号分隔的文件

时间:2017-08-19 11:35:01

标签: r csv data.table fread read.csv

我一直在尝试导入以下分号分隔文件:

# word  len;freq;mean;sens;npos;u;orthon;freqn;bgp  WN000000
fiber   "5;8.671;1;5;1;0;5;6.1;0;-1"    10000000
clad    "4;6.78;2;2;1;1;8;7.84;2026;-1" 10000000
tucker  "6;8.103;2;3;2;0.91829583405449;7;5.5;4547;-1"  10000000

我尝试了read.csvdata.table::fread,但没有运气。 read.csv识别一些标题,实际值全部在第一列之下:

 X..word.len freq mean sens npos  u orthon freqn bgp.WN000000
1 fiber\t5;8.671;1;5;1;0;5;6.1;0;-1\t10000000   NA   NA   NA   NA NA     NA    NA           NA
2 clad\t4;6.78;2;2;1;1;8;7.84;2026;-1\t10000000   NA   NA   NA   NA NA     NA    NA           NA
3 tucker\t6;8.103;2;3;2;0.91829583405449;7;5.5;4547;-1\t10000000   NA   NA   NA   NA NA     NA    NA           NA

fread识别第一列,但将所有其他列合并为一列。

  X..word    len.freq.mean.sens.npos.u.orthon.freqn.bgp WN000000
1   fiber                    5;8.671;1;5;1;0;5;6.1;0;-1 10000000
2    clad                 4;6.78;2;2;1;1;8;7.84;2026;-1 10000000
3  tucker  6;8.103;2;3;2;0.91829583405449;7;5.5;4547;-1 10000000

任何人都可以帮忙吗?

2 个答案:

答案 0 :(得分:3)

这是我尝试的(并根据David Arenburg的评论编辑)。

首先读取并处理标题行;然后在跳过第一行时读取剩余的行:

library(data.table)

header <- strsplit(readLines('test.txt', n = 1), '\\s+')[[1]][-1]
res <- fread('test.txt', skip = 1, header = FALSE)
setnames(res, 1:3, header)

res[, strsplit(header[2], ';')[[1]] :=
        tstrsplit(get(header[2]), ';', type.convert = TRUE, fixed = TRUE)[-10]]

res[, header[2] := NULL]

#      word WN000000 len  freq mean sens npos         u orthon freqn  bgp
# 1:  fiber 10000000   5 8.671    1    5    1 0.0000000      5  6.10    0
# 2:   clad 10000000   4 6.780    2    2    1 1.0000000      8  7.84 2026
# 3: tucker 10000000   6 8.103    2    3    2 0.9182958      7  5.50 4547

应该注意的是,输入文件的第二列中有;分隔的9个项目,但以下行有10个; - 分隔的项目。

答案 1 :(得分:2)

据我所知,你基本上有两个分离器在那里工作。可能值得手动处理,而不是使用标准读取功能。

读取文件,删除引号,然后用空格和分号分隔符分隔。

library( magrittr )
input <- readLines( "~/Desktop/Untitled" ) %>%
    gsub( '"|^# +', "", . ) %>%
    strsplit( "\\ +|;" )

将除第一行以外的所有内容转换为数据框。

input[-1] %>%
    do.call( what = rbind ) %>%
    as.data.frame()

然后使用第一行作为列名。我们需要在此处添加额外内容,因为您的标头没有足够的名称来覆盖您的数据。

names( df ) <- c( input[[1]][1:10], "fill.col", input[[1]][11] )

结果:

> df
    word len  freq mean sens npos                u orthon freqn  bgp fill.col WN000000
1  fiber   5 8.671    1    5    1                0      5   6.1    0       -1 10000000
2   clad   4  6.78    2    2    1                1      8  7.84 2026       -1 10000000
3 tucker   6 8.103    2    3    2 0.91829583405449      7   5.5 4547       -1 10000000
相关问题