k <- read.csv("kabuka.csv", header=FALSE) z <- read.csv("zaimu.csv", header=FALSE) colnames(k) <- c("名称","始値","高値","安値","終値","前日比","出来高", "日付","市場","コード") colnames(z) <- c("名称","単元","発行済","配当","EPS","BPS","株主資本比率", "ROE","ROA","決算年月","優待","コード") k2 <- unique(k) z2 <- unique(z) kz <- merge(k2, z2, by="コード")
できあがったデータフレームを覗くと,「-」, 「—」,「ウ」,「カ」,「ケ」,「—%」,「%」など,数値ではないものがあるのがわかる。データフレームの列にこのような数値ではないものが1つでもあると,その列は Factor になってしまう。表示しても数値のように見えるので気づきにくい(平均値などを求めようとすると気づかされる)。
そこでまず,各列のクラスを見てみる。
sapply(kz, class)
## コード 名称.x 始値 高値 安値 終値 前日比 出来高 日付 市場 名称.y ## "integer" "factor" "factor" "factor" "factor" "factor" "factor" "factor" "factor" "integer" "factor" ## 単元 発行済 配当 EPS BPS 株主資本比率 ROE ROA 決算年月 優待 ## "factor" "factor" "factor" "factor" "factor" "factor" "factor" "factor" "factor" "integer"
次に,数値にすべき列を数値にする。
以下のようにすると,warning は出るが,結果的には正しいものが得られる。
for (i in c(3:8, 12:18)) { kz[, i] <- as.numeric(as.character(kz[, i])) }
ちゃんと処理するためには,以下のようにする。ここでは,grepl を使って,「数値とはどういうものか」を「正規表現」を使って表し,適切な処理を選択している。
for (i in c(3:8, 12:18)) { temp <- as.character(kz[, i]) kz[, i] <- as.numeric(ifelse(!is.na(temp) & grepl("-*[0-9]+.*[0-9]*", temp), temp, NA)) }
この段階で,データ分析に使用できるデータフレームになった。
手始めに各変数の統計量を求めてみよう。
summary(kz[, c(3:8, 10, 12:18, 21)])
## 始値 高値 安値 終値 前日比 出来高 市場 単元 ## Min. : 6.0 Min. : 6.0 Min. : 5.0 Min. : 6 Min. :-25000.0 Min. : 0.00 Min. :1.00 Min. : 10.0 ## 1st Qu.: 356.0 1st Qu.: 361.8 1st Qu.: 352.2 1st Qu.: 335 1st Qu.: 0.0 1st Qu.: 1.17 1st Qu.:1.00 1st Qu.: 100.0 ## Median : 824.5 Median : 836.5 Median : 816.0 Median : 770 Median : 6.0 Median : 14.45 Median :1.00 Median : 500.0 ## Mean : 30707.7 Mean : 31278.8 Mean : 30250.9 Mean : 29359 Mean : 457.1 Mean : 550.29 Mean :2.25 Mean : 547.1 ## 3rd Qu.: 3257.5 3rd Qu.: 3332.5 3rd Qu.: 3220.0 3rd Qu.: 2862 3rd Qu.: 34.0 3rd Qu.: 154.25 3rd Qu.:5.00 3rd Qu.:1000.0 ## Max. :1410000.0 Max. :1440000.0 Max. :1400000.0 Max. :1430000 Max. :200000.0 Max. :59098.60 Max. :5.00 Max. :1000.0 ## NA's :273 NA's :273 NA's :273 NA's :25 NA's :418 NA's :273 NA's :738 ## 発行済 配当 EPS BPS 株主資本比率 ROE 優待 ## Min. :4.020e+03 Min. : 0.12 Min. :-131666.80 Min. :-20876.6 Min. :0.0010 Min. :-15.55560 Min. :1 ## 1st Qu.:5.160e+06 1st Qu.: 8.00 1st Qu.: 14.19 1st Qu.: 421.8 1st Qu.:0.2930 1st Qu.: 0.02740 1st Qu.:1 ## Median :1.861e+07 Median : 15.00 Median : 48.74 Median : 887.8 Median :0.4540 Median : 0.06720 Median :1 ## Mean :1.040e+08 Mean : 350.47 Mean : 824.33 Mean : 14774.2 Mean :0.4649 Mean : 0.04174 Mean :1 ## 3rd Qu.:6.470e+07 3rd Qu.: 36.00 3rd Qu.: 134.71 3rd Qu.: 1927.4 3rd Qu.:0.6300 3rd Qu.: 0.12055 3rd Qu.:1 ## Max. :1.086e+10 Max. :18000.00 Max. : 121652.00 Max. :992783.3 Max. :0.9860 Max. : 1.39200 Max. :1 ## NA's :62 NA's :757 NA's :296 NA's :268 NA's :128 NA's :170 NA's :2621
pattern <- "^(\\+|-)?([0-9]+$|[0-9]+\\.[0-9]+$|[0-9]+\\.[0-9]+E(\\+|-)?[0-9]+$)" pattern <- "^(\\+|-)?[0-9]+((\\.[0-9]+)?(E(\\+|-)?[0-9]+)?)?$" grepl(pattern, c("12", "+12", "-12", "1.23", "+1.23", "-1.23", "1.23E5", "-1.23E+04", "+1.23E-12", "1E2", "-1E+4"))
## [1] TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE
grepl(pattern, c("$12", "▲12", "---", "1.3%", "+1,23", "-1.23cm", "1.23e5", "-1.23+04", "+1.23/10^12", "1.", ".", ".123"))
## [1] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
文字列ベクトルの要素が数値を表すときには数値に変換,そうでなければ NA にする。
a <- c("123", "1a3", "1.23", "1,23", NA, "--") as.numeric(ifelse(grepl(pattern, a), a, NA))
## [1] 123.00 NA 1.23 NA NA NA
以下のようにすると,結果は同じになるが,警告メッセージが出る。
ifelse(grepl(pattern, a), as.numeric(a), NA) 警告メッセージ: In ifelse(grepl(pattern, a), as.numeric(a), NA): 強制変換により NA が生成されました