读取固定宽度文件中相同列的倍数 [英] Read multiples of same columns in a fixed width file

查看:14
本文介绍了读取固定宽度文件中相同列的倍数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

考虑a Stata .dct file中的以下几行,其中为Stata定义了如何读取this fixed width ASCII file(可以用任何平台上的任何ZIP软件解压缩):

start             type                            varname width  description
_column(24)       long                               rfv1   %5f  Patient's Reason for Visit #1            
_column(29)       long                               rfv2   %5f  Patient's Reason for Visit #2             
_column(34)       long                               rfv3   %5f  Patient's Reason for Visit #3             
_column(24)       long                             rfv13d   %4f  Patient's Reason for Visit #1 - broad     
_column(29)       long                             rfv23d   %4f  Patient's Reason for Visit #2 - broad     
_column(34)       long                             rfv33d   %4f  Patient's Reason for Visit #3 - broad     

基本上,此ASCII文件每行的第24到39个字符如下所示:

AAAAaBBBBbCCCCc

第一个宽码是AAAA,出于相同原因较窄的码是AAAAa,依此类推。

换句话说,因为代码本身具有层级结构,所以每行中的相同字符被读取两次,以创建两个不同的变量。

read.fwf相反,它只接受widths参数,这就排除了这种类型的重复读取。

有没有一种标准的方法来处理这种情况,而不是通过scan刷新整个文件并手动解析来从头开始重新创建轮子?

这里的背景是,我正在编写一个函数,以SAScii的风格解析这些.DCT文件,如果我可以为每个变量指定(start, width)对,而不仅仅是widths,我的工作将会简单得多。

推荐答案

我已经开始开发.DCT解析器,但失去了动力。我的预期使用场景实际上只是简单地解析文件并创建一个csvkitschema file,以允许我使用csvkit将文件从固定宽度转换为CSV。为此,一揽子计划是成功的,但它非常不完善,只进行了很少的测试。

需要注意的几个问题包括(1)并非所有DCT文件都有相同的列;(2)某些DCT文件具有隐式小数位指令,而我从未想出处理这些类型文件的方法。

您可以找到包的初始工作here

主要功能有:

  • dct.parser--如您所料。有一个读入前几行的"PREVIEW"参数,用于确定DCT文件是否包含您期望的所有列。
  • csvkit.schema--使用从dct.parser中提取的信息,从csvkit中创建具有in2csv所需相关列的CSV文件。
  • csvkit.fwf2csv--基本上是对csvkit的system调用。也可以在R之外完成

对于您的特定示例,我使用以下命令成功阅读:

## The extracted data file and the DCT file are in my downloads directory
setwd("~/Downloads/") 
dct.parser("ed02.dct", preview=TRUE) ## It seems that everything is there
temp <- dct.parser("ed02.dct")       ## Can be used as a lookup table later

## The next line automatically creates a csv schema file in your 
##   working directory named, by default, "your-dct-filename.csv"
csvkit.schema(temp) 
csvkit.fwf2csv(datafile = "ED02", schema="ed02.dct.csv", output="ED02.csv")

## I haven't set up any mechanism to check on progress...
## Just check the directory and see when the file stops growing :)
ED02 <- read.csv("ED02.csv")
我原本打算(但从未做过)的另一个替代方法是使用paste构造substr命令,sqldf可以使用这些命令来读入列中包含重叠数据的数据。有关入门示例,请参阅this blog post


更新:sqldf示例

如上所述,sqldf可以很好地利用dct.parser的输出,并使用substr读入您的数据。以下是您如何做到这一点的一个示例:

## The extracted data file and the DCT file are in my downloads directory
setwd("~/Downloads/") 
temp <- dct.parser("ed02.dct")       ## Can be used as a lookup table later

## Construct your "substr" command
GetMe <- paste("select", 
               paste("substr(V1, ", temp$StartPos, ", ",
                     temp$ColWidth, ") `", temp$ColName, "`", 
                     sep = "", collapse = ", "), 
               "from fixed", sep = " ")

## Load "sqldf"
library(sqldf)

fixed <- file("ED02")
ED02 <- sqldf(GetMe, file.format = list(sep = "_"))
dim(ED02)
# [1] 37337   260
可以看到,需要对sqldf行进行一些修改。特别是,由于sqldf使用read.csv.sql,它将数据中的任何逗号字符视为分隔符。您只需将其更改为数据中不需要的内容即可。

这篇关于读取固定宽度文件中相同列的倍数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆