R 导入不带行分隔符的固定宽度数据文件

R 导入不带行分隔符的固定宽度数据文件,r,import,dbf,R,Import,Dbf,我有固定宽度的数据文件(.dbf),没有行分隔符。下面是该数据文件的两行内容: 20141101 77h 3.210 0 3 20141102 76h 3.090 0 3 一行的宽度是c(8,4,7,41)对于日期(8)、一些时间度量(4)、数据点(7)和一些其他列,我可以将它们汇总到一个“rest”列(41)。一行之后没有分隔符,下一行只是附加

我有固定宽度的数据文件(.dbf),没有行分隔符。下面是该数据文件的两行内容:

20141101 77h  3.210                                  0    3 20141102 76h  3.090                                  0    3 
一行的宽度是
c(8,4,7,41)
对于日期(8)、一些时间度量(4)、数据点(7)和一些其他列,我可以将它们汇总到一个“rest”列(41)。一行之后没有分隔符,下一行只是附加到第一行。所有的时间步基本上都是连续地写在一行中。此文件中只有数字、字符和空白

使用
read.fwf('filepath',widths=c(8,4,7,41))
R在第一行之后由于缺少行分隔符而停止读取

当没有行分隔符时,是否有参数告诉
read.fwf()
何时开始读取新行?或者我应该使用不同的读取命令


提前谢谢。

也许不是最好的主意,但这应该行得通:

content <- scan('filepath','character',sep='~') # Warning choose a sep not appearing in datas to get the whole file.
# Split content in lines:
lines <- regmatches(content,gregexpr('.{60}',content))[[1]]
x <- tempfile()
write(lines,x)
data <- read.fwf(x, widths = c(8,4,7,41))
unlink(x)
其中:

        V1   V2      V3                                        V4
1 20141101  77h   3.210                                   0    3 
2 20141102  76h   3.090                                   0    3 
        VA  VB    VC VD VE
1 20141101 77h 3.210  0  3
2 20141102 76h 3.090  0  3
str\u match\u all
返回一个列表,这里有一个元素,因为只有一行作为输入,所以我们用
[[1]]]
删除它

现在返回的是5列,第一列是完全匹配的,其他列是捕获组,因此我们在第2列到第5列上对矩阵进行子集,以仅获得所需的4列,并将其包装在
as.data.frame
中,以在末尾获得data.frame


然后,您可以使用
colnames(d)来命名列,这是一种不同的、可能不那么优雅的解决方案,它具有
readLines
substr
trimws
separate
(tidyr)和
mutate\u all
(dplyr):

要获得不同的列名,只需将
c(paste0(“V”,字母[1:5])
替换为所需的列名向量


如果您想将列转换为正确的类,而不是转换为
字符
,您可以在
中使用
funs(ul=type.convert(trimws())
mutate\u all

除了其他答案之外,还有一些关于
dbf文件
的一般信息:

除非这是静态文件的一次性读取,否则最好先检查文件/字段结构,以防随时间变化。有关dbf文件的内部结构,请参阅

但也许更重要的是:

dbf文件中的每条记录前面都有一个字节作为删除标志。如果这是一个空格,则不会删除该记录,如果它是星号
*
,则会将该记录标记为删除(在打包文件之前不会从dbf文件中删除记录),您可能希望跳过这些记录。例如,数据的第一部分也可以被“
删除”
”覆盖

因此,在您的记录
c(8,4,7,41)
中,rest列(41)的最后一个字节实际上是它后面的记录的删除标志-并且文件中的最后一个记录对于该字段只有40个字节(但是如果您幸运的话,该文件有一个EOF标记(
0x1a
),因此可能您没有大小问题)


因此,您的记录实际上应该是:
c(1,8,4,7,40)
,其中
1
是删除标志,并提前开始一个字节。

您可以每60个字符添加一个行分隔符?()非常感谢您的建议,但是这个解决方案也存在同样的问题,即.fwf()在第一行之后停止。@Ben的确,我应该测试一下。我会用一个合适的解决方案更新答案。@Tensibai不会花太多时间在上面,因为Jaap的答案很好。但是谢谢你的建议!干净完美的解决方案。谢谢!@Ben Thanx:-)现在还添加了一个关于如何正确设置列类的注释。
td <- data.frame( trimws( str_match_all( content, "(.{8})(.{4})(.{7})(.{41})")[[1]][,2:5] ), stringsAsFactors=FALSE)
        X1  X2    X3     X4
1 20141101 77h 3.210 0    3
2 20141102 76h 3.090 0    3
txt <- readLines('filepath')
dfx <- data.frame(V1 = sapply(seq(from=1, to=nchar(txt), by=60),
                              function(x) substr(txt, x, x+59)))

library(dplyr)
library(tidyr)
dfx %>% 
  separate(V1, c(paste0("V",LETTERS[1:5])), c(8,12,19,55)) %>% 
  mutate_all(trimws)
        VA  VB    VC VD VE
1 20141101 77h 3.210  0  3
2 20141102 76h 3.090  0  3