【问题标题】:How to properly import a semicolon-separated file如何正确导入分号分隔的文件
【发布时间】:2017-08-19 11:35:00
【问题描述】:

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

# 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

有人可以帮忙吗?

【问题讨论】:

  • 这些都不能复制/粘贴到 R 中。请出示您的原始文本文件。
  • 你使用sep=";"read.csv 吗?
  • @G5W:我做到了。该命令的问题在于,实际值放在第一列,并且没有正确分布在标题中。
  • @RomanLuštrik:我现在就修。

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


【解决方案1】:

这是我尝试的(并根据 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 个由; 分隔的项目。

【讨论】:

【解决方案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

【讨论】:

  • 这看起来是一个不错的解决方案,尽管它给出了不正确的结果 - 第一列应该是“len”,而不是 word。感谢您的帮助!
  • 正如@mt1022 所注意到的,您的标头与您的数据不匹配。我让第一列名称是一个哈希,因为那是你的标题中的内容。如果您想更改名称,但仍要确保保留所有数据,则需要添加一个额外的列名。我已经更新了这样做。
猜你喜欢
  • 2019-09-26
  • 2018-07-23
  • 2017-02-14
  • 1970-01-01
  • 1970-01-01
  • 2019-09-19
  • 1970-01-01
  • 1970-01-01
  • 2011-08-20
相关资源
最近更新 更多