私はこのいフォーマットのデータセットをRセッションにロードしようとしています: http://www.cpc.ncep.noaa.gov/data/indices/wksst8110.for
Weekly SST data starts week centered on 3Jan1990
Nino1+2 Nino3 Nino34 Nino4
Week SST SSTA SST SSTA SST SSTA SST SSTA
03JAN1990 23.4-0.4 25.1-0.3 26.6 0.0 28.6 0.3
10JAN1990 23.4-0.8 25.2-0.3 26.6 0.1 28.6 0.3
17JAN1990 24.2-0.3 25.3-0.3 26.5-0.1 28.6 0.3
これまでのところ、私は行を読むことができます
x = readLines(path)
しかし、このファイルは区切り文字として「空白」と「-」を混ぜており、私は正規表現の専門家ではありません。これをすてきできれいなRデータフレームに変える助けを感謝します。ありがとう!
これは固定幅ファイルです。 read.fwf()
を使用して読み取ります。
x <- read.fwf(
file=url("http://www.cpc.ncep.noaa.gov/data/indices/wksst8110.for"),
skip=4,
widths=c(12, 7, 4, 9, 4, 9, 4, 9, 4))
head(x)
V1 V2 V3 V4 V5 V6 V7 V8 V9
1 03JAN1990 23.4 -0.4 25.1 -0.3 26.6 0.0 28.6 0.3
2 10JAN1990 23.4 -0.8 25.2 -0.3 26.6 0.1 28.6 0.3
3 17JAN1990 24.2 -0.3 25.3 -0.3 26.5 -0.1 28.6 0.3
4 24JAN1990 24.4 -0.5 25.5 -0.4 26.5 -0.1 28.4 0.2
5 31JAN1990 25.1 -0.2 25.8 -0.2 26.7 0.1 28.4 0.2
6 07FEB1990 25.8 0.2 26.1 -0.1 26.8 0.1 28.4 0.3
更新
パッケージreadr
(2015年4月リリース)は、シンプルで高速な代替手段を提供します。
library(readr)
x <- read_fwf(
file="http://www.cpc.ncep.noaa.gov/data/indices/wksst8110.for",
skip=4,
fwf_widths(c(12, 7, 4, 9, 4, 9, 4, 9, 4)))
速度の比較:readr::read_fwf()
はutils::read.fwf ()
よりも約2倍高速でした。
幅を決定する別の方法...
df <- read.fwf(
file=url("http://www.cpc.ncep.noaa.gov/data/indices/wksst8110.for"),
widths=c(-1, 9, -5, 4, 4, -5, 4, 4, -5, 4, 4, -5, 4, 4),
skip=4
)
Widths引数の-1は、無視する必要がある1文字の列があることを示し、widths引数の-5は、同様に無視する必要がある5文字の列があることを示します...
参照: https://www.inkling.com/read/r-cookbook-paul-teetor-1st/chapter-4/recipe-4-6
まず、その質問は、LeeksのCoursera「Get Data and Clean It」コースから直接のものです。質問には別の部分がありますが、難しい部分はファイルの読み取りです。
とはいえ、このコースは主に学習を目的としています。
私はRの固定幅手順が嫌いです。それは遅く、多数の変数の場合、特定の列などを無効にするのは非常にすぐに苦痛になります。
readLines()
を使用してから、substr()
を使用して変数を作成する方が簡単だと思います
x <- readLines(con=url("http://www.cpc.ncep.noaa.gov/data/indices/wksst8110.for"))
# Skip 4 lines
x <- x[-(1:4)]
mydata <- data.frame(var1 = substr(x, 1, 10),
var2 = substr(x, 16, 19),
var3 = substr(x, 20, 23),
var4 = substr(x, 29, 32) # and so on and so on
)
Hadley Wickhamのreadr
パッケージでread_fwf()
関数を使用できるようになりました。
ベースread.fwf()
と比較して、大幅なパフォーマンスの改善が期待されます。
こちら Rで固定幅ファイルを読み取るための代替のリストと、最速のベンチマークを提供します。
私が好むアプローチは、fread
とstringi
を組み合わせることです。最速のアプローチとして競争力があり、データをdata.table
として保存する追加の利点(IMO)があります。
library(data.table)
library(stringi)
col_ends <-
list(beg = c(1, 10, 15, 19, 23, 28, 32, 36,
41, 45, 49, 54, 58),
end = c(9, 14, 18, 22, 27, 31, 35,
40, 44, 48, 53, 57, 61))
data = fread(
"http://www.cpc.ncep.noaa.gov/data/indices/wksst8110.for",
header = FALSE, skip = 4L, sep = NULL
)[, lapply(1:(length(col_ends$beg)),
function(ii)
stri_sub(V1, col_ends$beg[ii], col_ends$end[ii]))
][ , paste0("V", c(2, 5, 8, 11)) := NULL]
# V1 V3 V4 V6 V7 V9 V10 V12 V13
# 1: 03JAN1990 23.4 -0.4 25.1 -0.3 26.6 0.0 28.6 0.3
# 2: 10JAN1990 23.4 -0.8 25.2 -0.3 26.6 0.1 28.6 0.3
# 3: 17JAN1990 24.2 -0.3 25.3 -0.3 26.5 -0.1 28.6 0.3
# 4: 24JAN1990 24.4 -0.5 25.5 -0.4 26.5 -0.1 28.4 0.2
# 5: 31JAN1990 25.1 -0.2 25.8 -0.2 26.7 0.1 28.4 0.2
# ---
# 1365: 24FEB2016 27.1 0.9 28.4 1.8 29.0 2.1 29.5 1.4
# 1366: 02MAR2016 27.3 1.0 28.6 1.8 28.9 1.9 29.5 1.4
# 1367: 09MAR2016 27.7 1.2 28.6 1.6 28.9 1.8 29.6 1.5
# 1368: 16MAR2016 27.5 1.0 28.8 1.7 28.9 1.7 29.6 1.4
# 1369: 23MAR2016 27.2 0.9 28.6 1.4 28.8 1.5 29.5 1.2
fread
は、先頭および末尾の空白を自動的に削除することに注意してください。これは望ましくない場合があり、その場合はstrip.white = FALSE
を設定します。
また、以下を実行することにより、列幅のベクトルww
から始めることもできます。
ww <- c(9, 5, 4, 4, 5, 4, 4, 5, 4, 4, 5, 4, 4)
nd <- cumsum(ww)
col_ends <-
list(beg = c(1, nd[-length(nd)]+1L),
end = nd)
そして、次のような負のインデックスを使用することで、より堅牢に除外する列を選択できます。
col_ends <-
list(beg = c(1, -10, 15, 19, -23, 28, 32, -36,
41, 45, -49, 54, 58),
end = c(9, 14, 18, 22, 27, 31, 35,
40, 44, 48, 53, 57, 61))
次に、col_ends$beg[ii]
をabs(col_ends$beg[ii])
で置き換え、次の行で:
paste0("V", which(col_ends$beg < 0))
最後に、列名もプログラムで読み取る場合は、readLines
でクリーンアップできます。
cols <-
gsub("\\s", "",
sapply(1:(length(col_ends$beg)),
function(ii)
stri_sub(readLines(URL, n = 4L)[4L],
col_ends$beg[ii]+1L,
col_ends$end[ii]+1L)))
cols <- cols[cols != ""]
(この手順をfread
と組み合わせるには、ヘッダー行を削除するためにテーブルのコピーを作成する必要があるため、大きなデータセットに対しては効率が悪いことに注意してください)
Rについてはわかりませんが、そのような行に一致する正規表現を提供できます。
\s[0-9]{2}[A-Z]{3}[0-9]{4}(\s{5}[0-9]+\.[0-9]+[ -][0-9]+\.[0-9]+){4}