6

.dctファイルを使用して.datファイルを読み取る必要があります。誰かがRを使ってそれをしましたか?

形式は次のとおりです。

dictionary {
  # how many lines per record
  _lines(1)
  # start defining the first line
  _line(1)

  # starting column / storage type / variable name / read format / variable label
  _column(1)    str8    aid    %8s    "respondent identifier"
  ...
}

「読み取り形式」は次のようなものです。

%2f        2 column integer variable
%12s      12 column string variable
%8.2f      8 column number with 2 implied decimal places. 

ストレージタイプについては、http://www.stata.com/help.cgi?datatypesで説明されています。

情報に使用される他のサイト:

http://library.columbia.edu/indiv/dssc/technology/stata_write.html

http://www.stata.com/support/faqs/data-management/reading-fixed-format-data/

.datファイルは、.dctファイルで指定された変数に対応する一連の数字です。(おそらく、これは固定幅の列のデータです)。

ここに実際の例があります:

.dtcファイル http://goo.gl/qHZOk

データ http://goo.gl/FRGRF

stataサイトの具体例は次のとおりです。

ファイル(この.dat場合は「test.raw」)

C1245A101George Costanza
B1223B011Cosmo Kramer

.dctファイル_

dictionary using test2.raw {
 _column(1)     str5     code   %5s
 _column(2)     int      call   %4f
 _column(6)     str1     city   %1s
 _column(7)     int      neigh  %3f
 _column(10)    str16    name   %16s
}

結果のデータファイル:

      +-----------------------------------------------+
      |  code   call   city   neigh              name |
      |-----------------------------------------------|
   1. | C1245   1245      A     101   George Costanza |
   2. | B1223   1223      B      11      Cosmo Kramer |
      +-----------------------------------------------+
4

2 に答える 2

14

@thelatemail は、続行する方法についてスポットオンです。より堅牢なソリューションを開始するためにまとめた小さな関数を次に示します。

read.dat.dct <- function(dat, dct) {
    temp <- readLines(dct)
    pattern <- "_column\\(([0-9]+)\\)\\s+([a-z0-9]+)\\s+([a-z0-9_]+)\\s+%([0-9]+).*"
    classes <- c("numeric", "character", "character", "numeric")
    metadata <- setNames(lapply(1:4, function(x) {
        out <- gsub(pattern, paste("\\", x, sep = ""), temp)
        out <- gsub("^\\s+|\\s+$|.*\\{|\\}", "", out)
        out <- out[out != ""]
        class(out) <- classes[x] ; out }), 
                         c("StartPos", "Str", "ColName", "ColWidth"))
    read.fwf(dat, widths = metadata[["ColWidth"]], 
             col.names = metadata[["ColName"]])
}

エラーチェック、関数の一般化などに関して、やらなければならないことはまだたくさんあります。たとえば、この関数は、@thelatemail が質問に追加した例にあるように、重複する列では機能しません。"StartPos[n] + ColWidth[n]" は "StartPos[n+1]" と等しくなければならないという形式のエラー チェックを使用して、エラー メッセージが表示されてそうでない場合、ファイルの読み取りを停止できます。さらに、結果のデータのクラスは、関数によって生成されread.fwf、引数を使用して割り当てられた「メタデータ」リストから抽出することもできcolClassesます。

デモ用の dat ファイルと dct ファイルを次に示します。

次の 2 行をコピーしてテキスト エディターに貼り付け、作業ディレクトリに "test.dat" として保存します。

C1245A101George Costanza
B1223B011Cosmo Kramer

次の行をコピーしてテキスト エディターに貼り付け、作業ディレクトリに「test.dct」として保存します。

dictionary using test.dat {
    _column(1)     str1     code   %1s
    _column(2)     int      call   %4f
    _column(6)     str1     city   %1s
    _column(7)     int      neigh  %3f
    _column(10)    str16    name   %16s
}

次に、関数を実行します。

read.dat.dct(dat = "test.dat", dct = "test.dct")
#   code call city neigh            name
# 1    C 1245    A   101 George Costanza
# 2    B 1223    B    11    Cosmo Kramer

更新: 改善された機能 (まだ改善の余地がたくさんあります)

read.dat.dct <- function(dat, dct, labels.included = "no") {
    temp <- readLines(dct)
    temp <- temp[grepl("_column", temp)]
    switch(labels.included,
           yes = {
               pattern <- "_column\\(([0-9]+)\\)\\s+([a-z0-9]+)\\s+(.*)\\s+%([0-9]+)[a-z]\\s+(.*)"
               classes <- c("numeric", "character", "character", "numeric", "character")
               N <- 5
               NAMES <- c("StartPos", "Str", "ColName", "ColWidth", "ColLabel")
           },
           no = {
               pattern <- "_column\\(([0-9]+)\\)\\s+([a-z0-9]+)\\s+(.*)\\s+%([0-9]+).*"
               classes <- c("numeric", "character", "character", "numeric")
               N <- 4
               NAMES <- c("StartPos", "Str", "ColName", "ColWidth")
           })
    metadata <- setNames(lapply(1:N, function(x) {
        out <- gsub(pattern, paste("\\", x, sep = ""), temp)
        out <- gsub("^\\s+|\\s+$", "", out)
        out <- gsub('\"', "", out, fixed = TRUE)
        class(out) <- classes[x] ; out }), NAMES)

    metadata[["ColName"]] <- make.names(gsub("\\s", "", metadata[["ColName"]]))

    myDF <- read.fwf(dat, widths = metadata[["ColWidth"]], 
             col.names = metadata[["ColName"]])
    if (labels.included == "yes") {
        attr(myDF, "col.label") <- metadata[["ColLabel"]]
    }
    myDF
}

それはあなたのデータでどのように機能しますか?

temp <- read.dat.dct(dat = "http://dl.getdropbox.com/u/18116710/21600-0009-Data.txt", 
                     dct = "http://dl.getdropbox.com/u/18116710/21600-0009-Setup.dct",
                     labels.included = "yes")
dim(temp)                     # How big is the dataset?
# [1] 180  40
head(temp[, 1:6])             # What do the first few columns & rows look like?
#   CASEID      AID RRELNO RPREGNO H3PC1.H3PC1 H3PC2.H3PC2
# 1      1 57118381      5       1           1           1
# 2      2 57134970      1       2           1           1
# 3      3 57135078      1       1           1           1
# 4      4 57135078      5       1           1           1
# 5      5 57164981      1       1           7           3
# 6      6 57191909      1       3           1           1
head(attr(temp, "col.label")) # What are the variable labels?
# [1] "CASE IDENTIFICATION NUMBER"             "RESPONDENT IDENTIFIER"                 
# [3] "ROMANTIC RELATIONSHIP NUMBER"           "RELATIONSHIP PREGNANCY NUMBER"         
# [5] "S23Q1 1 TOLD PARTNER PREGNANT-W3"       "S23Q2 MONTHS PREG WHEN TOLD PARTNER-W3"

元の例ではどうですか?

read.dat.dct("test.dat", "test.dct", labels.included = "no")
#   code call city neigh            name
# 1    C 1245    A   101 George Costanza
# 2    B 1223    B    11    Cosmo Kramer
于 2013-01-09T18:52:11.697 に答える
10

データは基本的に固定幅のデータ ファイルであるため、datファイルを読み取ることができる場合があります。?read.fwf.dat

ここを参照してください-乱雑なメモ帳データの整理column(X)-辞書ファイルの値を.dct幅として使用します。

辞書ファイルを使用readLinesして情報を抽出し、それを呼び出しの引数に渡すことができread.fwfます。

例: 「変数名」はcol.names=引数と一致し、「ストレージ タイプ」はcolClasses=引数と一致します。

ただし、これにはいくつかの手動処理があります。

于 2013-01-09T06:03:48.330 に答える