先日のNagoya.R #18で、以下の記事のグループ分け関数についてお話させてもらった。
この関数について吉野睦さんから、もっと簡単に同じことができることを教えていただきました。この場をお借りして感謝申し上げます。ありがとうございました。ご提供いただいたコードを許可をいただいた上で以下に転載させていただきます。
rm(list=ls())
# エクセル名簿から貼り付けるとこんな感じ(改行だけ)
x <- c("
川口勇作
川口勇作
川口勇作
川口勇作
川口勇作
川口勇作
")
# こんな感じに縦に並んでいるものを貼り付ける
# 改行コードで分割する
x <- strsplit(x,"\n")[[1]] # なぜかリスト形式になってしまうので[[1]]
x <- x[!nchar(x)==0] # 空文字列を取り除く
# ここからがメインルーチン
class <- 10
index <- rep(1:class,len=length(x)) # クラス番号生成
index <- sample(index) # クラス番号をシャッフルする
x <- split(x,index) # クラス分けする
print(x,quote=FALSE) # 名前のダブルコーテーションを取って表示
流れとしては以下のとおり。
エクセルから、ダブルコーテーションなし、カンマなし、改行のみ
で貼り付けたことを想定し、 strsplit()関数で名前データ生成
あとはメインルーチンで、
クラス数を指定
rep()関数でクラス番号を生成
sample()関数でシャッフル
split()関数でクラス分け
print()関数で、ダブルコーテーションなし表示
自分はfor文の中でfor文を回すという効率の悪いやり方をしていた。以前Python Bootcampに参加したときにも感じたことだが、今の自分にはこういう効率の良いコードを書く能力が欠けているようだ。フィードバックをいただける環境に感謝。
【追記 2018/9/2】吉野さんから以下のような追加情報をいただきました。ありがとうございました。
最後の、
print(x,quote=FALSE)を、次のように変更して頂くと、リスト形式がデータフレームに変更できます。
y <- lapply(x,function(z){c(z,rep("",max(sapply(x,length))-length(z)))}) xx <- do.call(cbind,y) print(xx,quote=FALSE)