No.22256 R findInterval()関数  【明石】 2017/01/23(Mon) 18:22

青木先生,
いつもお世話になり,ありがとうございます,明石と申します。

Rプログラムについて,ご教示いただきたいことが出てきました。

何卒どうぞ,よろしくお願いいたします。

ーーー

年齢(integer)のベクトルデータを読み込んで,
以下のような対応表に基づいて,
年齢(integer) → 年代(factor)にデータ変換しようと思い,
この掲示板で紹介されていました便利な関数 findInterval を適用しました。
#----------------------------------------
# 年齢 ⇒ 年代(10階級)
#----------------------------------------
#  -19   "01:-19"
# 20-24   "02:20-24"
# 25-29   "03:25-29"
# 30-34   "04:30-34"
# 35-39   "05:35-39"
# 40-44   "06:40-44"
# 45-49   "07:45-49"
# 50-54   "08:50-54"
# 55-59   "09:55-59"
# 60-    "10:60-"
#----------------------------------------
作成したRコードは,以下です。
jun <- findInterval(年齢, c(0, 20, 25, 30, 35, 40, 45, 50 ,55, 60))
cut <- c("01:-19", "02:20-24", "03:25-29", "04:30-34", "05:35-39", "06:40-44", "07:45-49", "08:50-54", "09:55-59", "10:60-")
年代 <- factor(jun, label=cut)
色々なデータへ適用したところ,
例えば,年齢が「19 以下」の区間のデータがないなどのように,
findInterval で指定した区間にデータがない場合には,エラーになるようです。

私のプログラムにミスがあるのでしょうか?

青木先生にご教示いただきたいことは,以下の2点です。
何卒どうぞ,よろしくお願いいたします。

(1) 指定した区間にデータがない場合に,エラーになる事象は,
  関数の仕様として,正しい振る舞いでしょうか?

(2) 上記エラーを回避する対処方法があるでしょうか?

ご教示いただければ,大変に助かります。
何卒どうぞ,よろしくお願いいたします。

No.22258 Re: R findInterval()関数  【青木繁伸】 2017/01/24(Tue) 10:10

findInterval でエラーになっているのではありません。
set.seed(12345)
年齢 <- sample(18:63, 10, replace=TRUE)
年齢
jun <- findInterval(年齢, c(0, 20, 25, 30, 35, 40, 45, 50 ,55, 60))
cut <- c("01:-19", "02:20-24", "03:25-29", "04:30-34", "05:35-39", "06:40-44", "07:45-49", "08:50-54", "09:55-59", "10:60-")
年代 <- factor(jun, label=cut)
では,
> jun
[1] 8 9 8 9 5 3 4 6 8 10
> table(jun)
jun
3 4 5 6 8 9 10
1 1 1 1 3 2 1
と なり,factor は 7 種類の値しか取らないのに cut が 10 種のラベルであるため,「factor(jun, label = cut) でエラー: 無効な 'labels' です; 長さ 10 は 1 または 7 であるべきです」のエラーになるのです。
対処法は,factr の実際の値に対してlabels を用意するということになるでしょう。
#set.seed(12345)
年齢 <- sample(18:63, 10, replace=TRUE)
年齢
int = 5 # 階級幅
from <- floor(min(年齢)/int)*int
to <- ceiling(max(年齢)/int)*int
vec <- seq(from, to, by=int)
vec
jun <- findInterval(年齢, vec)
index <- as.integer(names(table(jun))) # 階級が連続しているとは限らない
labels <- NULL
for (i in seq_along(table(jun))) {
value <- (index[i]-1)*int+from
labels <- c(labels, sprintf("%02d:%d-%d", i, value, value+int-1))
}
labels
年代 <- factor(jun, labels=labels)
年代
data.frame(年齢, jun, 年代)

No.22259 【御礼】 Re: R findInterval()関数  【明石】 2017/01/24(Tue) 12:57

青木先生,
いつもお世話になり,ありがとうございます,明石と申します。

苦慮していましたので,有難いご教示をいただき,大変に助かりました。

「factor の実際の値に対してlabels を用意する」ことで対処する方向で検討します。

いつもありがとうございます。

● 「統計学関連なんでもあり」の過去ログ--- 048 の目次へジャンプ
● 「統計学関連なんでもあり」の目次へジャンプ
● 直前のページへ戻る