No.06803 データフレームの中身の置換  【波音】 2008/06/13(Fri) 14:31

> Temperature <- c(20, 21, 17, 16, 19, 14, 22)
> Weather <- c("曇", "曇", "曇", "晴", "曇", "晴", "雨")
> Week <- c("日", "月", "火", "水", "木", "金", "土")
> Sales <- c(86, 107, 111, 86, 109, 91, 99)
# データフレームの作成
> dat <- data.frame(TEMPERATURE = Temperature, WEATHER = Weather,
+ WEEK = Week, SALES = Sales)
こういうデータフレームがあったとして,例えば,WEEKの日,月,火,,,を英語(ローマ字)あるいは数値に置き換える場合にはどうするのが適切でしょうか。

自分でこのような関数を作らなくても,もっと簡単な方法があるものでしょうか,,,
myfunc <- function(a, myn){
mydata <- c()
n <- length(a)
n2 <- length(myn)
for(i in 1:n){
for(j in 1:n2){
if(a[i] == levels(a)[j]) mydata[i] <- myn[j]
}
}
mydata <- as.factor(mydata)
}

# 英語に置き換える
> chikan <- myfunc(dat$WEEK, c("Tue", "Fri", "Mon", "Wed", "Sat", "Sun", "Thu"))
# データフレームdatのWEEKにchikanのデータを挿入
> dat$WEEK <- chikan
ちなみに,因子(factor)の水準(Levels)の順番はどのようにして決まっているのでしょう?漢字だと
[1] 日 月 火 水 木 金 土
Levels: 火 金 月 水 土 日 木
となりますし,英語だと
[1] Sun Mon Tue Wed Thu Fri Sat
Levels: Fri Mon Sat Sun Thu Tue Wed
となるのは,どうしてこのような順番になるのでしょうか(特に知っておかなければならないことでもないのでしょうが,,,やはり文字コードとかで優先順位がきめらているのでしょうか)。

No.06804 Re: データフレームの中身の置換  【青木繁伸】 2008/06/13(Fri) 14:36

> どうしてこのような順番になるのでしょうか

文字コードの順ですね。文字コードは,辞書順に与えられている。ということで,辞書順と言っても良いでしょう。

漢字の場合はどうなっているのかな?
波音さんは Windows (cp932) ですね。utf-8 環境だと,
> dat$WEEK
[1] 日 月 火 水 木 金 土
Levels: 土 日 月 木 水 火 金
となります。
ということで,環境が変わると置き換えプログラムが正しく動かない可能性はありますね。

問題の解決には何段階か必要ですが,第一段階は,望んだ順で factor にしてもらうために,factor 関数の levels 引数を使うと良いでしょう。場合によっては labels 引数も。
> w <- c("Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat")
> w <- factor(w, levels=w)
> levels(w)
[1] "Sun" "Mon" "Tue" "Wed" "Thu" "Fri" "Sat"
> x <- c("male", "female", "female","male", "male")
> y <- factor(x)
> levels(y)
[1] "female" "male"
> z <- factor(x, levels=c("male", "female"))
> levels(z)
[1] "male" "female"
> w <- factor(x, levels=c("male", "female"), labels=c("男", "女"))
> levels(w)
[1] "男" "女"

No.06805 Re: データフレームの中身の置換  【青木繁伸】 2008/06/13(Fri) 15:26

エンコーディングによって,また,factor の引数設定によって異なっているが,以下のようにする。
> dat$WEEK # 今のデータの levels を確認する
(levels 関数を使う方がよいかも)
[1] 日 月 火 水 木 金 土
Levels: 土 日 月 木 水 火 金 # ★ この並び順に注意
# Levels を置き換える。前から順に
> levels(dat$WEEK) <- c("Sat", "Sun", "Mon", "Thu",
"Wed", "Tue", "Fri")
> dat$WEEK # どのように置き換えられたか
[1] Sun Mon Tue Wed Thu Fri Sat
Levels: Sat Sun Mon Thu Wed Tue Fri
# ★ 上の並び順が保存されていることに注意
なお,levels の置き換えは一対一でなくても良いので,再カテゴリー化に使える。たとえば,例に挙げられたデータフレームの dat$WEATHER について
> dat$WEATHER
[1] 曇 曇 曇 晴 曇 晴 雨
Levels: 晴 曇 雨
> levels(dat$WEATHER) <- c("天気がよい", "天気が悪い",
"天気が悪い")
> dat$WEATHER
[1] 天気が悪い 天気が悪い 天気が悪い 天気がよい 天気が悪い
天気がよい 天気が悪い
Levels: 天気がよい 天気が悪い
のようにできる。

No.06809 Re: データフレームの中身の置換  【波音】 2008/06/14(Sat) 22:02

回答ありがとうございます。

やはり順番は文字コードに基づいたものだったのですね。

順番を任意のようにする場合は引数のlevelsを指定すればよかったのですね。でも,labelsでmaleやfemaleを男,女とすると,labelsの方が優先されるようですが,このようにする利点はどういうときなのかチョッと想像できません,,,(^_^;)

levels() <- c()とすることで,このような書き換え(置き換え)ができるとは,これはけっこう便利ですね。こうすれば,わざわざ繰り返しの処理を使わなくてもいいわけですね。

No.06819 Re: データフレームの中身の置換  【青木繁伸】 2008/06/15(Sun) 19:21

> でも,labelsでmaleやfemaleを男,女とすると,labelsの方が優先されるようですが,このようにする利点はどういうときなのか

levels は,元のデータフレームのどの値を何にするかということ,labels はそれにどういう名前を付けること(まんまですね)。

元々のデータが数値で入力されているようなときに違いがわかりやすいかなあ?
> x <- c(1,2,1,2,2,1,1,1,2)
> y <- factor(x, levels=c(1,2), labels=c("男", "女"))
> y
[1] 男 女 男 女 女 男 男 男 女
Levels: 男 女

No.06822 Re: データフレームの中身の置換  【波音】 2008/06/15(Sun) 20:17

あっ,なるほど。
そういうことでしたか。

逆に
> x <- c("M", "F")
> y <- factor(x, levels=c("M", "F"), labels=c(1, 2))
のようにラベルを数値にすることもできるわけですね。数値と文字とで考えると分かりやすいです。

度々の回答ありがとうございました。

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