读取固定宽度文件中相同列的倍数 [英] Read multiples of same columns in a fixed width file
本文介绍了读取固定宽度文件中相同列的倍数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!
问题描述
考虑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屋!
查看全文