2017-11-08 15 views
0

read.tableを使用して多くのテキストファイルをRに読み込もうとしています。ほとんどの場合、定義済みの列を持つクリーンなテキストファイルがあります。R:空白と不等な列数のテキストファイルを読む

私は読んしようとしているデータは、テキストファイルの空白と長さはレポートによって異なることがわかりますftp://ftp.cmegroup.com/delivery_reports/live_cattle_delivery/102317_livecattle.txt

から来ています。 ftp://ftp.cmegroup.com/delivery_reports/live_cattle_delivery/102317_livecattle.txt ftp://ftp.cmegroup.com/delivery_reports/live_cattle_delivery/100917_livecattle.txt

私の目的は、これらのテキストファイルの多くを読み、データセットにそれらを組み合わせることです。

もし私がそれらの1つを読むことができれば、コンパイルは問題ではありません。しかし、テキストファイルの形式のためにいくつかの問題が発生しています。

1)FIRMSの数はレポートによって異なります。たとえば、インポートするデータの行が3行(つまり、そのデータを扱っている3つの企業)であり、時には10が存在することもあります。

2)空白が認識されています。たとえば、FIRMセクションの下にDeliveries(DEL)とReceipts(REC)の列があります。それは、このセクションで読み込まれたデータは、次のようになります。しかし、私はfomattingでこれを読んだとき、すべて台無しにして、ブランク値

3のためにNAを入れていません

df <- data.frame("FIRM_#" = c(407, 685, 800, 905), 
    "FIRM_NAME" = c("STRAITS FIN LLC", "R.J.O'BRIEN ASSOC", "ROSENTHAL COLLINS LL", "ADM INVESTOR SERVICE"), 
    "DEL" = c(1,1,15,1), "REC"= c(NA,18,NA,NA)) 

)上記の問題テキストファイルの「YARDS」と「FUTURE DELIVERIES SCHEDULED」のセクションを適用します。

私はテキストファイルのセクションを読み込み、それに応じてフォーマットしようとしましたが、企業の数が日々変わるのでコードは一般化しません。

ご協力いただければ幸いです。

答えて

1

ここでは、データをダウンロードするためにrvestを使用してゼロから始まり、多くの書式設定が含まれています。一般的な考え方は、列を区切るために使用される固定幅を特定することです - 私はこの目的のためにSOから少しの助けを借りてlinkです。

cat()tempfile()と組み合わせてread.fwf()を使用できます。私の最初の試みでは、いくつかの書式設定の問題のためにこれはうまくいかなかったので、最終的なテーブル形式を得るためにいくつかの行を追加しました。

多分もっと洗練されたオプションやショートカットがありますが、少なくとも私の答えはあなたを始めなければなりません。もちろん、必要なデータの部分に応じて、行の選択、分割テーブルの幅の識別を適応させる必要があります。これが解決されたら、すべてのウェブサイトをループしてデータを収集することができます。これが役に立ったら...

library(rvest) 
library(dplyr) 

page <- read_html("ftp://ftp.cmegroup.com/delivery_reports/live_cattle_delivery/102317_livecattle.txt") 

table <- page %>% 
    html_text("pre") %>% 
    #reformat by splitting on line breakes 
    { unlist(strsplit(., "\n")) } %>% 
    #select range based on strings in specific lines 
    "["(.,(grep("FIRM #", .):(grep("  DELIVERIES SCHEDULED", .)-1))) %>% 
    #exclude empty rows 
    "["(., !grepl("^\\s+$", .)) %>% 
    #fix width of table to the right 
    { substring(., 1, nchar(gsub("\\s+$", "" , .[1]))) } %>% 
    #strip white space on the left 
    { gsub("^\\s+", "", .) } 


headline <- unlist(strsplit(table[1], "\\s{2,}")) 

get_split_position <- function(substring, string) { 

    nchar(string)-nchar(gsub(paste0("(^.*)(?=", substring, ")"), "", string , perl=T)) 

} 

#exclude first element, no split before this element 
split_positions <- sapply(headline[-1], function(x) { 

    get_split_position(x, table[1]) 

}) 


#exclude headline from split 
table <- lapply(table[-1], function(x) { 

    substring(x, c(1, split_positions + 1), c(split_positions, nchar(x))) 

}) 

table <- do.call(rbind, table) 
colnames(table) <- headline 

#strip whitespace 
table <- gsub("\\s+", "", table) 

table <- as.data.frame(table, stringsAsFactors = FALSE) 
#assign NA values 
table[ table == "" ] <- NA 
#change column type 
table[ , c("FIRM #", "DEL", "REC")] <- apply(table[ , c("FIRM #", "DEL", "REC")], 2, as.numeric) 

table 
# FIRM #   FIRM NAME DEL REC 
# 1 407  STRAITSFINLLC 1 NA 
# 2 685 R.J.O'BRIENASSOC 1 18 
# 3 800 ROSENTHALCOLLINSLL 15 NA 
# 4 905 ADMINVESTORSERVICE 1 NA 
+0

ありがとうございます。これは大きな助けになりました。すべてのものは、最後のセクションでデータを引き出すことを円滑に期待しています。 0100の数字はレポートからレポートに変わるため、テキストファイル全体でジェンナルライズできません。グラバー機能にファイルの最後に行くように指示する方法はありますか?助けてくれてありがとう – EDennnis

+0

文字ベクトルの最終行、ひいてはテキスト行を得るためには、単純に 'vector [length(vector)]'を使うことができます。代わりに、 'tail(vector、1)'がうまくいくと思います。 –

+0

未解決の問題がまだ残っている場合は、正しく機能しなかったものを指定して、失敗したコードを入力してください。これにより、簡単に手助けすることができます(データの解析はケース固有のタスクです。可能な限り正確にコード内のクリティカルポイント)。それ以外の場合は、回答に感謝してください。 –

関連する問題