No.22299 R ftable()関数   【明石】 2017/03/11(Sat) 19:03

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

先日は,件名「状態遷移を表形式で整理」でご教示いただきまして,誠にありがとうございました。
大変に助かりました,とても良い勉強をさせていただきました。
改めて御礼を申し上げます。

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

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

ーーー

タイタニックのデータを例に,やりたいことをご説明します。

タイタニックのデータをデータフレーム dat に格納しています。
> dim(dat)
[1] 2201 4

> colnames(dat)
[1] "Class" "Age" "Sex" "Alive"

> ftable(dat)

Alive 死亡 生還
Class Age Sex
1等 子ども 女性 0 1
男性 0 5
大人 女性 4 140
男性 118 57
2等 子ども 女性 0 13
男性 0 11
大人 女性 13 80
男性 154 14
3等 子ども 女性 17 14
男性 35 13
大人 女性 89 76
男性 387 75
乗務員 子ども 女性 0 0
男性 0 0
大人 女性 3 20
男性 670 192
左側のカラムから順にソートされて整形されます。

もし,以下のように,右側からソートされるような整形をしたいと思った場合に,
どのようにすればよろしいのでしょうか?
               Alive 死亡 生還
Class Age Sex
1等 大人 男性 118 57
2等 大人 男性 154 14
3等 大人 男性 387 75
乗務員 大人 男性 670 192
1等 子ども 男性 0 5
2等 子ども 男性 0 11
3等 子ども 男性 35 13
乗務員 子ども 男性 0 0
1等 大人 女性 4 140
2等 大人 女性 13 80
3等 大人 女性 89 76
乗務員 大人 女性 3 20
1等 子ども 女性 0 1
2等 子ども 女性 0 13
3等 子ども 女性 17 14
乗務員 子ども 女性 0 0
色々と考えていますが,できません。
ご教示いただければ大変に助かります。

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

No.22300 Re: R ftable()関数   【青木繁伸】 2017/03/11(Sat) 23:27

引数指定で処理できるようではなく,また,既存の関数もないので,自分で書くしかないかな??

結果のヘッダ部分が ftable のものと違うが,以下のような感じで
> a = ftable(dat)
> b = data.frame(a)
> # ftable の結果をデータフレームにして,右の列から並べ替える
> # 要素が factor のときは,decreasing を要素ごとに指定することができないので,as.integer で整数コードの方を用いる
> # method はデフォルトではなく "radix" を指定すること
> # 並べ替えのための以下の 1 行は,それぞれのデータフレームにより適切に記述のこと
> result = b[order(as.integer(b$Sex), as.integer(b$Age), as.integer(b$Class),
+ decreasing=c(TRUE, TRUE, FALSE),
+ method="radix"),]
> result
Class Age Sex Alive Freq
13 1等 大人 男性 死亡 118
29 1等 大人 男性 生還 57
14 2等 大人 男性 死亡 154
30 2等 大人 男性 生還 14
15 3等 大人 男性 死亡 387
31 3等 大人 男性 生還 75
16 乗務員 大人 男性 死亡 670
32 乗務員 大人 男性 生還 192
9 1等 子ども 男性 死亡 0
25 1等 子ども 男性 生還 5
10 2等 子ども 男性 死亡 0
26 2等 子ども 男性 生還 11
11 3等 子ども 男性 死亡 35
27 3等 子ども 男性 生還 13
12 乗務員 子ども 男性 死亡 0
28 乗務員 子ども 男性 生還 0
5 1等 大人 女性 死亡 4
21 1等 大人 女性 生還 140
6 2等 大人 女性 死亡 13
22 2等 大人 女性 生還 80
7 3等 大人 女性 死亡 89
23 3等 大人 女性 生還 76
8 乗務員 大人 女性 死亡 3
24 乗務員 大人 女性 生還 20
1 1等 子ども 女性 死亡 0
17 1等 子ども 女性 生還 1
2 2等 子ども 女性 死亡 0
18 2等 子ども 女性 生還 13
3 3等 子ども 女性 死亡 17
19 3等 子ども 女性 生還 14
4 乗務員 子ども 女性 死亡 0
20 乗務員 子ども 女性 生還 0
>
> # これ以降は,データフレームの列名等に左右されないように汎用的に記述する
> name = levels(result[,ncol(result)-1]) # この時点では,result の右から2列目が目的の列名(例では "Alive")
> # name はその水準名(例では "死亡","生還"),これを後で使う
> lname = length(name) # lname はその長さ
> Freq = matrix(result[,"Freq"], byrow=TRUE, ncol=lname) # 集計数がある列から数値を取り出し,水準数を列とする行列にする
> result = cbind(result[seq(1, nrow(result), by=lname), 1:(ncol(result)-2)], Freq) # 行名と集計数の行列をバインド
> names(result)[ncol(result)-lname:1+1] = name # 集計数の列名を付ける
> print(result, row.names=FALSE)
Class Age Sex 死亡 生還
1等 大人 男性 118 57
2等 大人 男性 154 14
3等 大人 男性 387 75
乗務員 大人 男性 670 192
1等 子ども 男性 0 5
2等 子ども 男性 0 11
3等 子ども 男性 35 13
乗務員 子ども 男性 0 0
1等 大人 女性 4 140
2等 大人 女性 13 80
3等 大人 女性 89 76
乗務員 大人 女性 3 20
1等 子ども 女性 0 1
2等 子ども 女性 0 13
3等 子ども 女性 17 14
乗務員 子ども 女性 0 0
しかしまあ,row.vars と col.vars を使って,以下のようにした方が簡単でしょう?
Class を一番左に置きたいという理由がないならば
男性と女性,大人と子どもの前後関係を変えるのは,factor でまえもって処理しておけばよいだけ,だし。
> ftable(dat, row.vars=c("Sex", "Age", "Class"), col.vars="Alive")
Alive 死亡 生還
Sex Age Class
女性 子ども 1等 0 1
2等 0 13
3等 17 14
乗務員 0 0
大人 1等 4 140
2等 13 80
3等 89 76
乗務員 3 20
男性 子ども 1等 0 5
2等 0 11
3等 35 13
乗務員 0 0
大人 1等 118 57
2等 154 14
3等 387 75
乗務員 670 192

No.22301 Re: R ftable()関数   【明石】 2017/03/12(Sun) 11:45

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

ご丁寧に,色々な方法をご教示くださいまして,誠にありがとうございます。
とても勉強になります。

最初,ftable の結果をデータフレームにして並べ替えることを検討しましたが,
うまくいきませんでした。

青木先生がお示しをしてくださいましたプログラムを見て,理解できました。

心から御礼を申し上げます。
ありがとうございました。

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