2015アーカイブ

カテゴリカルデータからダミー変数を作成するR関数を自作(複数列対応可)(その後)

追記(2017.1.3)

makedummiesパッケージがCRANに登録されました。ブログの このページ を参照して下さい。

内容

以前、 このページ でカテゴリカルデータからダミー変数を作成するR関数を紹介しました。

このブログ自体それほどアクセスがあるわけではありませんが、検索される際のキーワードとして「R ダミー変数」が最も多かったです。

そこでこの関数をGitHubで公開しました(https://github.com/toshi-ara/makedummies)。

Rからは

## install.packages("devtools") # パッケージをインストールしていない場合
library(devtools)
install_github("toshi-ara/makedummies")

でインストールできます。

使用方法はGitHubの例を参照して下さい。

久しぶりにウィルススキャンをしてみたら……

久しぶりにclamavで自宅コンピュータのウィルススキャンをしてみました。

clamscan -ri ~

すると1個だけウィルス感染ファイルが検出されました。

./(path)/LineInst.exe: Win.Trojan.Nimnul-22 FOUND

今はLINEをアカウントごと削除していることもあり、ファイルを速攻で削除しました。

CORESERVERにGitPrepをインストールするも失敗

経緯

現在契約しているCORESERVERに GitPrep (GitHubクローン)をインストールして使用しようとしましたが、結局うまくいかなかったという報告です。

インストール操作

Gitのインストール

CORESERVERにはgitがインストールされていないため、まずそこから始めました。

git-2.6.2(現時点での最新版)のソースコードをダウンロードし、以下のようにインストールしました。

tar xzf git-2.6.2.tar.gz
cd git-2.6.2
make configure
./configure --prefix=$HOME/local
make
make install

その後、.bashrcに

export PATH=$HOME/local/bin:$PATH

の行を追加してパスを通しました。

GitPrepのインストールおよび設定

以下の順にインストールおよび設定を行いました。

  1. ソースコード(当時の最新版であるバージョン1.10)をダウンロードし、ホームページの内容に従ってインストール
  2. gitprep.my.confを作成し、インストールされたgitの場所などを適切に指定
  3. http://arat.xyz/gitprep/gitprep.cgi にアクセスし、adminユーザーおよび一般ユーザーを作成

ここまでは正しく動作しました。

一般ユーザーでログインした後に、「Initialize this repository with a README」にチェックを入れて新規レポジトリを作成しようとすると、「Internal error」が表示されてしまいレポジトリの作成に失敗してしまいました。

原因の究明

経過をGitPrepの作者である木本さんに連絡するなどして原因を明らかにしようとしました。

現時点で分ったことは以下の通りです。

  1. 新規レポジトリ作成時にgit pushを行うが、 CGIプログラムとして動かした場合にエラーが出る。
    • サーバにSSH接続してコマンドラインから同じことを行ってもエラーは出ずに正しく動作する。
    • CGIプログラムではなく、localhost:10020でアクセスして使用する方法では何の問題もなく使用できる。
  2. かなりの試行錯誤の結果、簡単なシェルスクリプト(CGI)を書いて、 webから実行してエラーメッセージを表示させたところ、 git push時に以下のエラーが出ました(ちなみにCGIプログラムをコマンドラインから直接実行するとエラーは出ませんでした)。
error: cannot create thread: Cannot allocate memory
fatal: send-pack: unable to fork off sideband demultiplexer
error: cannot create thread: Cannot allocate memory
fatal: bad object 13f4ebbd6ef5a638511e543e16b0ebc544695403

つまり、 CGIプログラムでgit pushを実行させた際に新たなスレッドが作成されないのが原因のようです。 Apacheの設定が関係しているのかもしれません。

これ以上は自分での解決は無理と判断したので、これまでの内容をCORESERVERのサポートに伝えました。ただし、Apacheの設定を変更するなどの処置が必要になるかもしれないため解決は難しいかもしれません。

現在はさくらレンタルサーバのスタンダード(無料お試し)上で動かしているため、問題なく動作しています。 CORESERVERのサポートからの回答次第ではさくらレンタルサーバに完全移行することも考えています。

CORESERVERにEmacsをインストールする

経緯

CORESERVERにSSH接続してファイルの編集を行うことがあります。その時にサーバに用意されているエディタがvimでした。

vimに慣れる目的で少しだけ使用しましたが、コピー&ペーストのやり方も知らないためすぐに断念しました。

そこでいつも使用しているEmacs(最新版は24.5)をサーバにインストールしました。

Emacsのインストール

ソースコードのダウンロードおよびサーバへのアップロード

(省略)

インストール操作

tar xzf emacs-24.5.tar.gz
cd emacs-24.5/
./configure --prefix=$HOME/local --without-gnutls
make
make install

でインストールできました。

また、

--without-gnutls

のオプションですが、これをつけないとビルド時にエラーが出ました。

ターミナル上では画像を使用しないため、不必要なオプションをオフにした方がいいのでしょうが、今回はそこまでは行いませんでした。

とりあえずこれでサーバ上でのファイルの編集が楽になりそうです。その前にある程度、Emacsの設定もしなければなりませんが。

追記

2015.11.13

コンパイル時のオプションを追加しました。

./configure --prefix=$HOME/local --without-sound \
            --without-xml2 --without-gpm --without-xpm \
            --without-jpeg --without-tiff --without-png \
            --without-gif --without-imagemagick \
            --without-gnutls \
            --without-x
--without-xml2

がないとEmacsの起動時に警告が出ます。

ファイルを自動でバイトコンパイルさせないための設定

普段は auto-async-byte-compile.el を使用して Emacsの設定ファイルを保存時に自動コンパイルするように設定しています。

(require 'auto-async-byte-compile)
(add-hook 'emacs-lisp-mode-hook 'enable-auto-async-byte-compile-mode)

ただし、るびきちさんのTwitterか何かで「変数を設定しただけのファイルはバイトコンパイルしない」というコメントを見たような記憶があります(記憶が非常にあいまいのためもし違っていたら申し訳ありません)。

そこでどのように設定するのかを調べてみました。

検索方法が悪いのかなかなか見つかりませんでしたが、最終的に Emacsのマニュアル に載っているのを見つけました。

ファイルの先頭に

;; -*-no-byte-compile: t; -*-

のようにしてローカル変数を設定すればいいようです。

これで自動でバイトコンパイルさせることはなくなりました。

Emacsのパッケージ管理のレポジトリにMELPA-stableを追加する

経緯

Emacs-24.5を使用しており、パッケージ管理のレポジトリとして ELPA(gnu)の他に MELPAとMarmalade、orgを追加しています。

しかし、 MELPAに登録されているパッケージの中には亢進頻度が高いものもあり、時々アップグレードによって不具合が生じる場合もあります。

そのため、 MELPAに登録されているパッケージでも安定版で使用したい場合がありました。

そのような時に検索していると このページ にMELPA-stableのことが載っていました。

そこでMELPA-stableを導入したのでその時のメモを残しておきます。ただし、日本語の情報があまりなかったため少し大変でした。

MELPA-stableの導入

レポジトリの登録

このページ の内容に従って.emacs.elに

(add-to-list 'package-archives
             '("melpa-stable" . "https://stable.melpa.org/packages/") t)

を追加します。 Emacs-24以降を使用する場合にはそれ以外の設定は不要です。

パッケージの移行

M-x package-list-packages

を実行し、下の方にある installed となっているパッケージを選択します。 (バージョン番号)(melpa-stable) という箇所を選択すると インストール画面に移行します。

この時、既にMELPAからインストールされているパッケージのフォルダは削除せずに別な場所に保存しておいた方がいいかもしれません。

また、場合によっては MELPA-stableではなくMarmaladeからインストールすることもあるため、どちらからインストールしたのかをメモしておいた方がいいです。

始めはメモしておかなかったため、後でもう一度調べ直すことになりました。結構大変でした。

package-pinned-packages変数の設定

この状態でパッケージのアップグレードを行うと、 MELPAのパッケージが候補に上がってきました。

これでは安定版をインストールした意味がないので、 MELPA-stable版の場合にはMELPA版をインストールしないようにするための設定を調べたところ、 このページ が見つかりました。

package-pinned-packages という変数に パッケージ名とレポジトリを登録すればいいようです。

少し長いですが、現時点での私の設定を載せておきます。

(setq package-pinned-packages
      '(
        (ac-R                  . "marmalade")
        (ace-isearch           . "melpa-stable")
        (ace-jump-buffer       . "melpa-stable")
        (ace-jump-mode         . "melpa-stable")
        (ace-link              . "melpa-stable")
        (ace-pinyin            . "melpa-stable")
        (ace-window            . "melpa-stable")
        (ag                    . "melpa-stable")
        (alert                 . "melpa-stable")
        (async                 . "melpa-stable")
        (auto-complete         . "melpa-stable")
        (avy                   . "melpa-stable")
        (bind-key              . "melpa-stable")
        (bm                    . "marmalade")
        (button-lock           . "melpa-stable")
        (calfw                 . "melpa-stable")
        (color-theme           . "marmalade")
        (ctable                . "melpa-stable")
        (dash                  . "melpa-stable")
        (deferred              . "melpa-stable")
        (descbinds-anything    . "marmalade")
        (diffview              . "melpa-stable")
        (diminish              . "melpa-stable")
        (dired-details         . "marmalade")
        (el-mock               . "melpa-stable")
        (el-x                  . "melpa-stable")
        (elscreen              . "melpa-stable")
        (elscreen-mew          . "melpa-stable")
        (epl                   . "melpa-stable")
        (ess                   . "melpa-stable")
        (ess-R-data-view       . "melpa-stable")
        (ess-R-object-popup    . "melpa-stable")
        (ess-smart-underscore  . "melpa-stable")
        (f                     . "melpa-stable")
        (flycheck              . "melpa-stable")
        (flyspell-lazy         . "melpa-stable")
        (fuzzy                 . "melpa-stable")
        (git-commit            . "melpa-stable")
        (gntp                  . "melpa-stable")
        (guide-key             . "melpa-stable")
        (helm                  . "melpa-stable")
        (helm-ag               . "melpa-stable")
        (helm-core             . "melpa-stable")
        (helm-swoop            . "melpa-stable")
        (highlight-defined     . "melpa-stable")
        (ht                    . "melpa-stable")
        (htmlize               . "marmalade")
        (hydra                 . "melpa-stable")
        (ibuffer-vc            . "melpa-stable")
        (ido-completing-read+  . "melpa-stable")
        (ido-vertical-mode     . "melpa-stable")
        (imenus                . "melpa-stable")
        (julia-mode            . "melpa-stable")
        (kill-or-bury-alive    . "melpa-stable")
        (letcheck              . "melpa-stable")
        (log4e                 . "melpa-stable")
        (m-buffer              . "melpa-stable")
        (magit                 . "melpa-stable")
        (magit-popup           . "melpa-stable")
        (metaweblog            . "melpa-stable")
        (mew                   . "melpa-stable")
        (migemo                . "melpa-stable")
        (morlock               . "melpa-stable")
        (mykie                 . "melpa-stable")
        (noflet                . "marmalade")
        (oauth                 . "marmalade")
        (org                   . "org")
        (org-gcal              . "melpa-stable")
        (org2blog              . "melpa-stable")
        (ox-pandoc             . "melpa-stable")
        (pandoc-mode           . "melpa-stable")
        (paredit               . "melpa-stable")
        (parsebib              . "melpa-stable")
        (passthword            . "melpa-stable")
        (pcre2el               . "marmalade")
        (pcsv                  . "melpa-stable")
        (php-mode              . "melpa-stable")
        (pkg-info              . "melpa-stable")
        (popup                 . "melpa-stable")
        (popwin                . "melpa-stable")
        (rainbow-delimiters    . "melpa-stable")
        (request               . "melpa-stable")
        (request-deferred      . "melpa-stable")
        (revive                . "marmalade")
        (s                     . "melpa-stable")
        (sexp-move             . "melpa-stable")
        (smartrep              . "melpa-stable")
        (smex                  . "melpa-stable")
        (stan-mode             . "melpa-stable")
        (stripe-buffer         . "melpa-stable")
        (unkillable-scratch    . "melpa-stable")
        (use-package           . "melpa-stable")
        (vline                 . "marmalade")
        (with-editor           . "melpa-stable")
        (ml-rpc                . "melpa-stable")
        (xml-rpc               . "marmalade")
        ))

これでMELPAではなく、MELPA-stableやMarmaladeを参照するようになりました。

Vine Linux 6.3でgitを私的rpmパッケージ化

経緯

Emacs-24.5でMELPAからmagitをインストールして使用しています。

しかし、いつの頃からか.gitフォルダが存在していても認識されなくなりした。

調べてみるとログには以下のように書かれていました。

Also note that starting with the ‘2.1.0’ release, Magit requires at least Emacs ‘24.4’ and Git ‘1.9.4’. You should make sure you have at least these releases installed before updating Magit. And if you connect to remote hosts using Tramp, then you should also make sure to install a recent enough Git version on these hosts.

そこで Vine Linux 6.3のgitのバージョンを調べてみると

$ rpm -qa | grep git
git-1.7.4.2-1vl6.x86_64

とやはり対応していませんでした。

gitのビルド

ソースコードからのビルド

そこでソースコードからビルドしました。今回インストールしたgitのバージョンは2.5.3です。

ソースコードは GitHub からダウンロードしました。

tar xzf git-2.5.3.tar.gz
cd git-2.5.3
make prefix=/usr/local all
sudo make prefix=/usr/local install

で/usr/local以下にインストールされます。

この状態でmagitをアップグレードすると動作するようになりました。

私的パッケージ化

せっかくなのでrpmパッケージ化しました。本来のパッケージと名前を区別するために my_git としています。

からダウンロードできます。

/usr/local以下にインストールされるため、本来のパッケージに含まれるファイルを上書きすることはありません。

org-modeで(require ‘ob-R)とするとエラーが出ていたのを解決(訂正)

経緯

Emacsのパッケージ管理をpackageで行っています。 2015.8.3より後のバージョンのorgをインストールした場合に、 org-bableでR-modeを使用するために

(require 'ob-R)

とすると

Debugger entered--Lisp error: (invalid-function org-babel-header-args-safe-fn)

のようにエラーが出ていました。

試行錯誤の結果、解決できたのでメモを残しておきます。

追記(2015.9.29)

以下の「方法」の内容は間違いの可能性があるため訂正します。従来のELPA(gnu)レポジトリでインストールできました。

org-modeのメーリングリストを見ていると同じエラーの投稿がありました( 質問 とそれに対する 回答 )。

回答には

When this error has been reported in the past, it has been due to
another version of Org being loaded during the update.  Please uninstall
and then reinstall before any version of Org is loaded.

と書かれていました。

つまり、

  1. 一度(新しいバージョンの)Orgをアンインストールする。
  2. Emacsを起動して古いバージョンのOrgがロードされる前に(新しいバージョンの)Orgをインストールする。

必要があるようです。

何回もインストールとアンインストールを繰り返して試行錯誤した結果、

  1. (念のため)Emacsをシャットダウンする。
  2. emacs -Q でまっさらな環境のEmacsを起動する(ここが重要)。
  3. M-x list-packages からorg(gnu版のみ表示される)をインストールする。
  4. Emacsを起動する。

でエラーが起こらなくなりました。

同じ症状で困っている方がいれば試してみて下さい。

方法(以下の内容は必要ありません)

このページ の内容を参考にしました。

.emacs.elに

;; (require 'package)   ;; 設定済のためコメントアウト
(add-to-list 'package-archives '("org" . "http://orgmode.org/elpa/") t)

を追加し、

M-x list-packages

とすると、

org                20150914      available  gnu        Outline-based notes management and organizer
org                20150914      available  org        Outline-based notes management and organizer

のようにorg版のorgも表示されるようになるので、こちらをインストールします。

これで

(require 'ob-R)

としてもエラーが出なくなりました。

補足

このページ によると、開発版ではstan-modeに対応しているようです(2015.9.20閲覧)。 2015.9.3のgitのログ に載っていました。

近いうちに取り込まれて使用できるようになるでしょう。楽しみです。

Vine Linuxでタイル型ウィンドウマネージャ(ratpoisonとawesome)を私的パッケージ化

経緯

Vine Linuxにはタイル型ウィンドウマネージャのパッケージが存在していません。

そこで全くの個人的な興味から、タイル型ウィンドウマネージャとして ratpoison (version 1.4.8)と awesome (version 3.5.6)をパッケージ化したのでrpmファイルをアップロードします。

ただし個人的には fluxbox (version 1.3.5)をカスタマイズして愛用しています。

インストール

ダウンロード先

このページ から適切なrpmファイルをダウンロードしてインストールして下さい。

  • Vine Linux6ならVine6
  • VineSeed(次期Vine Linux7)ならVine7

のページに進み、さらに

  • 32ビット環境であればi686
  • 64ビット環境であればx86_64

のページに進みます。

ratpoison

Vine Linux6とVineSeed(Vine Linux7)用のパッケージを用意しました。

  • ratpoison-1.4.8-***.rpm

をダウンロードしてインストールします。

awesome

VineSeed(Vine Linux7)用のパッケージだけを用意しました。 Vine Linux6では依存パッケージのバージョンが古いためビルドできませんでした。

  • lgi-0.9.0-1vl7.***.rpm
  • awesome-3.5.6-1vl7.***.rpm

の2つのパッケージをダウンロードします。先にlgi(awesomeの依存パッケージ)をインストールしてから awesomeをインストールします。

注意事項

使用方法

ここでは操作方法については書きませんが、他のページで十分調べてから使用するようにして下さい。特に「ログアウト」の方法を知らずにログインしてしまうと大変です(経験済みです)。

責任回避のようなもの

今回はあくまでも私的にパッケージ化したものであり、 Vine Linuxのオフィシャルなものではありません。ですのでパッケージの説明文は非常にいいかげんなものです。また、ライセンスの記載も正しくないものも含まれています。

また、使用した事によって生じた不具合などについては責任を取ることはできません。

カテゴリカルデータからダミー変数を作成するR関数を自作(複数列対応可)

追記(2017.1.3)

makedummiesパッケージがCRANに登録されました。ブログの このページ を参照して下さい。

追記(2015.12.26)

GitHubで関数を公開しました。ブログの このページ を参照して下さい。

経緯

Rのglm関数を用いて重回帰分析を行う際には、カテゴリカルデータを自動的にダミー変数に変換してくれるため、あまり苦労しません。

現在、個人的にRStanを勉強中であり、同じ解析を行うためには自分でダミー変数を作成する必要があります。さらにカテゴリカルデータと数値データが混在しているとそれだけで非常に大変です。

そこで群馬大学の青木先生が公開されているmake.dummy関数( http://aoki2.si.gunma-u.ac.jp/R/src/make.dummy.R )をもとにして関数を作成しました。

作成した関数

(2015.9.6追記)以下のプログラムを修正したものを記事の下に掲載しています。こちらを使用せずにそちらを参考にして下さい。

# http://aoki2.si.gunma-u.ac.jp/R/src/make.dummy.R
make.dummy <- function(dat, basal_level= FALSE, sep = "_") {
    name <- colnames(dat)
    level <- levels(dat[,1])
    if (!is.data.frame(dat))
        dat <- as.data.frame(dat)
    ncat <- ncol(dat)
    dat[, 1:ncat] <- lapply(dat, function(x) {
        if (is.factor(x)) {
            return(as.integer(x))
        } else {
            return(x)
        }
    })
    mx <- sapply(dat, max)
    start <- c(0, cumsum(mx)[1:(ncat-1)])
    nobe <- sum(mx)
    ## modified
    res <- t(apply(dat, 1, function(obs) 1:nobe %in% (start+obs))) + 0
    colnames(res) <- paste(name, level, sep = sep)
    if (basal_level == FALSE) res <- res[,-1]
    return(res)
}


make.dummys <- function(dat, ...) {
    n <- ncol(dat)
    res_list <- lapply(seq(n), function(i) {
        tmp <- as.data.frame(dat[,i])
        colnames(tmp) <- colnames(dat)[i]
        if (is.factor(dat[,i])) {       # factor or ordered
            make.dummy(tmp, ...)
        } else {
            tmp
        }
    })

    res <- NULL
    for (i in seq(n)) {
        res <- cbind(res, res_list[[i]])
    }
    return(res)
}

解説

make.dummy関数

青木先生が公開されているmake.dummy関数を少しだけ改変しました。データはデータフレーム形式で渡します。

変更点は以下の点です。

  1. 基準となるカテゴリーを削除できるように変更
    • basal_level引数が FALSE => 基準となるカテゴリーを削除する(デフォルト)
    • basal_level引数が TRUE => 基準となるカテゴリーを削除しない
  2. 列名を追加
    • sep引数で変数名とカテゴリー名を連結する文字列を設定(デフォルトは”_”)

(2015.9.6追記)新バージョンではこの関数は削除しました。ただし、引数の説明はこのまま使用できます。

make.dummys関数

元データが複数の列からなっている場合にも一度にダミー変数に変更するようにしました。

また、カテゴリカルデータ以外(主に数値データ)の場合にはそのまま出力するようにしました。

ですので make.dummys関数を使用すればOKです。引数sepとbasal_levelも使用可能です。

使用例

カテゴリカルデータの場合

基準となるカテゴリーを削除する場合

dat <- data.frame(x = factor(rep(c("a", "b", "c"), each = 3)))
dat$x
make.dummys(dat)
[1] a a a b b b c c c
Levels: a b c

      x_b x_c
 [1,]   0   0
 [2,]   0   0
 [3,]   0   0
 [4,]   1   0
 [5,]   1   0
 [6,]   1   0
 [7,]   0   1
 [8,]   0   1
 [9,]   0   1

基準となるカテゴリーを削除しない場合

make.dummys(dat, basal_level = TRUE)
     x_a x_b x_c
[1,]   1   0   0
[2,]   1   0   0
[3,]   1   0   0
[4,]   0   1   0
[5,]   0   1   0
[6,]   0   1   0
[7,]   0   0   1
[8,]   0   0   1
[9,]   0   0   1

変数名とカテゴリー名を連結する文字列を変更

make.dummys(dat, sep = ":")
     x:b x:c
[1,]   0   0
[2,]   0   0
[3,]   0   0
[4,]   1   0
[5,]   1   0
[6,]   1   0
[7,]   0   1
[8,]   0   1
[9,]   0   1

順序のあるカテゴリカルデータの場合

dat <- data.frame(x = factor(rep(c("a", "b", "c"), each = 3)))
dat$x <- ordered(dat$x, levels = c("a" ,"c" ,"b"))
dat$x
make.dummys(dat)
[1] a a a b b b c c c
Levels: a < c < b

      x_c x_b
 [1,]   0   0
 [2,]   0   0
 [3,]   0   0
 [4,]   0   1
 [5,]   0   1
 [6,]   0   1
 [7,]   1   0
 [8,]   1   0
 [9,]   1   0

カテゴリカル変数は意味のある語が使用されることが多いため、実際にはordered変数を使用して順序のあるカテゴリカルデータとして扱うことが多いと思います。

数値データの場合

dat <- data.frame(x = rep(1:3, each = 3))
dat$x
make.dummys(dat)
  x
1 1
2 1
3 1
4 2
5 2
6 2
7 3
8 3
9 3

数値データはそのまま出力されます。

複数の列をもつ場合

2つのカテゴリカルデータ

dat <- data.frame(
    x = factor(rep(c("a", "b", "c"), each = 3)),
    y = factor(rep(1:3, each = 3))
)
make.dummys(dat)
     x_b x_c y_2 y_3
[1,]   0   0   0   0
[2,]   0   0   0   0
[3,]   0   0   0   0
[4,]   1   0   1   0
[5,]   1   0   1   0
[6,]   1   0   1   0
[7,]   0   1   0   1
[8,]   0   1   0   1
[9,]   0   1   0   1

それぞれダミー変数として出力されます。

カテゴリカルデータと数値データ

dat <- data.frame(
    x = factor(rep(c("a", "b", "c"), each = 3)),
    y = rep(1:3, each = 3)
)
make.dummys(dat)
  x_b x_c y
1   0   0 1
2   0   0 1
3   0   0 1
4   1   0 2
5   1   0 2
6   1   0 2
7   0   1 3
8   0   1 3
9   0   1 3

カテゴリカルデータと数値データが混在してもカテゴリカルデータのみがダミー変数に変換されます。

追記

2015.9.6

プログラムを修正しました。

  • make.dummys関数の1つだけで動作するように改変しました。
  • ダミー変数に変換するプログラムも簡潔にしました。
  • 得られる結果は同じです。
  • ただし、元データの行ラベルも再現するように変更しました。

2015.9.11

プログラムを少し修正しました。

統計学関連なんでもあり のNo. 21771から始まるスレッドの青木先生の書き込みをもとに変更しました。

こちらの方が行数は増えますが、処理の内容が明確でした。

make.dummys <- function(dat, basal_level = FALSE, sep = "_") {
    n_col <- ncol(dat)
    name_col <- colnames(dat)
    name_row <- rownames(dat)

    result <- NULL
    for (i in seq(n_col)) {
        ## process each column
        tmp <- dat[,name_col[i]]
        if (is.factor(tmp)) {
            ## factor or ordered => convert dummy variables
            level <- levels(droplevels(tmp))
            ## http://aoki2.si.gunma-u.ac.jp/taygeta/statistics.cgi
            ## No. 21773
            m <- length(tmp)
            n <- length(level)
            res <- matrix(0, m, n)
            res[cbind(seq(m), tmp)] <- 1
            ## res <- sapply(level, function(j) ifelse(tmp == j, 1, 0))
            colnames(res) <- paste(name_col[i], level, sep = sep)
            if (basal_level == FALSE) {
                res <- res[,-1]
            }
        } else {
            ## non-factor or non-ordered => as-is
            res <- as.matrix(tmp)
            colnames(res) <- name_col[i]
        }
        result <- cbind(result, res)
    }
    rownames(result) <- name_row
    return(result)
}