2

改行も改行もないフラットファイルの固定幅があります(AS400からのダンプ)。

このファイルをRdata.frameにロードするにはどうすればよいですか?

textConnectionとread.fwfのさまざまな組み合わせを試しましたが、役に立ちませんでした。

以下のコードはRstudioをクラッシュさせるので、システムに過負荷をかけていると思います。

len以下は24376400です。これは、私が通常read.tableを使用してロードするファイルに関しては飼いならされています。レコード長は400です。

SASと同様に、設定する必要のあるRECLENパラメーターはありますか?EOL ="\n"または"\r \ n"を設定するオプションはありますか?ありがとうございました。

fname <- "AS400FILE.TXT"
len <- file.info(fname)$size
conn <- file(fname, 'r')
contents <- readChar(conn, len)
close(conn)

df <- read.fwf( textConnection(contents) , widths=layout$length , sep="")

> dput(layout)
structure(list(start = c(1L, 41L, 81L, 121L, 161L, 201L, 224L, 
226L, 231L, 235L, 237L, 238L, 240L, 280L, 290L, 300L, 305L, 308L, 
309L, 330L, 335L, 337L, 349L, 350L, 351L, 355L, 365L), end = c(40L, 
80L, 120L, 160L, 200L, 223L, 225L, 230L, 234L, 236L, 237L, 239L, 
279L, 289L, 299L, 304L, 307L, 308L, 329L, 334L, 336L, 348L, 349L, 
350L, 354L, 364L, 400L), length = c(40L, 40L, 40L, 40L, 40L, 
23L, 2L, 5L, 4L, 2L, 1L, 2L, 40L, 10L, 10L, 5L, 3L, 1L, 21L, 
5L, 2L, 12L, 1L, 1L, 4L, 10L, 36L), label = c("TITLE", "SUFFIX", 
"ADDRESS1", "ADDRESS2", "ADDRESS3", "CITY", "STATE", 
"ZIP", "ZIP+4", "DELIVERY", "CHECKD", "FILLER", "NAME", 
"SOURCECODE", "ID", "FILLER", "BATCH", "FILLER", "FILLER", 
"GRID", "LOT", "FILLER", "CONTROL", 
"ZIPIND", "TROUTE", "SOURCEA", "FILLER")), .Names = c("start", 
"end", "length", "label"), class = "data.frame", row.names = c(NA, 
-27L))
> dim(layout)
[1] 27  4
> 
4

1 に答える 1

3

これに使用できますreadChar

最初にいくつかのサンプルデータを作成します(質問からわかる限り、形式はあなたが説明したとおりだと思いますか?つまり、列ごとに指定された幅のテキストの壁で、ファイル全体に新しい行はありません):

lengths <- c(2,3,4,2,3,4)
nFields <- length(lengths)
nRows   <- 10              # let's make 10 rows.
contents <- paste(letters[sample.int(26,size=sum(lengths)*nRows,replace=TRUE)],
                  collapse="")
#> contents
#[1] "lepajmcgcqooekmedjprkmmicm.......
cat(contents,file='test.txt')

私はそれを行うための3つの方法を考えることができます、それぞれの間のさまざまな違い:

行数が事前にわかっている場合は、次のことができます。

# If you know #rows in advance..
conn <- file('test.txt','r')
data <- readChar( conn, rep(lengths,nRows) )
close(conn)
# reshape data to dataframe
df <- data.frame(matrix(data,ncol=nFields,byrow=T))

それ以外の場合は、ループを使用できます(ファイルを一度読み込んで行数を計算してから、もう一度解析するのはなぜですか?)

# Otherwise use a loop
conn <- file('test.txt','r')
df <- data.frame(matrix(nrow=0,ncol=6)) # initialise 0-row data frame
while ( length(data <- readChar(conn, lengths)) > 0 ) {
    df[nrow(df)+1,] <- data
}
close(conn)

または、すでにすべてがcontents文字列に含まれているため、次を使用して文字列を分割できますsubstring

# have already read in contents so can calculate nRows
nRows <- floor(nchar(contents)/sum(lengths)) # 10 for my example
starts <- c(0,cumsum(lengths[-nFields]))
df3 <- data.frame(t(
                    vapply( seq(1,nRows*sum(lengths),sum(lengths)),
                    function(r) 
                        substring(contents,starts+r,starts+r+lengths-1),
                    rep("",nFields) )))

できるだけ少ないファイル読み取りでそれを実行したい場合は、2番目または3番目の方法をお勧めします。

3番目の方法は、私にとって最もエレガントな方法ですが、全体contentsを一度に読み取る必要があります。これは、ファイルサイズによっては、実行できない場合があります。

その場合は、一度に1セットのnFieldsフィールドのみを読み取る2番目の項目に進みます。

事前に行数がわからない限り、最初の試みはお勧めしません。これは私の最初の試みでした。最初にファイルを読み込んで行数を決定してから、ファイルを閉じて再度読み込む必要があるため、お勧めしません。そのルートをたどりたい場合は、方法3を使用してください。ただし、他の方法で行数が事前にわかっている場合は、この方法を使用できます。

于 2012-02-27T04:24:11.400 に答える