gpt4 book ai didi

读取固定宽度文件中相同列的倍数

转载 作者:行者123 更新时间:2023-12-04 10:47:22 25 4
gpt4 key购买 nike

考虑来自 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 从头开始​​重新创建轮子?在整个文件中并手动解析它?

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

最佳答案

我已经开始研究 .DCT 解析器,但失去了动力。我的预期使用场景实际上只是简单地解析文件并创建一个 csvkit schema file允许我使用 csvkit 将文件从固定宽度转换为 csv。为此,该软件包是成功的,但它非常未完善并且仅进行了非常少的测试。

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

您可以在包 here 上找到初始工作。 .

主要功能是:

  • dct.parser ——做你所期望的。有一个“预览”参数读取前几行,让您确定 DCT 文件是否包含您期望的所有列。
  • csvkit.schema -- 使用从 dct.parser 中提取的信息, 使用 in2csv 所需的相关列创建一个 csv 文件来自 csvkit。
  • csvkit.fwf2csv -- 基本上是一个 system调用 csvkit。也可以在 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 build 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 ,它将数据中的任何逗号字符视为分隔符。您可以将其更改为您不希望在数据中出现的内容。

    关于读取固定宽度文件中相同列的倍数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16172793/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com