Rあんなときこんなとき(tokyo r#12)

6,012 views

Published on

Published in: Technology
0 Comments
15 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total views
6,012
On SlideShare
0
From Embeds
0
Number of Embeds
651
Actions
Shares
0
Downloads
63
Comments
0
Likes
15
Embeds 0
No embeds

No notes for slide

Rあんなときこんなとき(tokyo r#12)

  1. 1. Rあんなときこんなとき~いつか役に立つ(かもしれない)Tips~ 2011年3月5日 第12回 TokyoR @sfchaos
  2. 2. 本発表の趣旨� Rに初めて触れた頃,それまでに使っていたCや C++に比べて利便性が高いと思ったものの,お作 法など分からないことがたくさんありました.� 本発表では,特に私がRを触れた初期の頃に調べ たりつまづいたポイントを中心に,6つのTipsに ついてクイズ形式で議論したいと思います. 1
  3. 3. アジェンダ1. 自己紹介2.クイズで議論! RのTips3. まとめ 2
  4. 4. アジェンダ1. 自己紹介2.クイズで議論! RのTips3. まとめ 3
  5. 5. 自己紹介� TwitterID: @sfchaos� 出身地: 埼玉県� 職業:コンサルタント � 数年間,金融工学のモデル構築・データ解析 � 最近,大規模データ解析に着手(Hadoop/Mahout)� 趣味:登山� 学生時代の専攻は物理・応用数学(非線形力学 系・カオス) 4
  6. 6. � 私とR � データ解析の仕事に携わりRを使い始めた. � 最近はRでの大規模データ解析に興味がある.2007 2008 2009 2010 2011 データ解析 (金融工学) 大規模 データ 解析 Rの基礎とプログラミング技法 Software for R Tips data analysis (Webサイト) RjpWiki CRANマニュアル (Webサイト) 5
  7. 7. � 私とR � データ解析の仕事に携わりRを使い始めた. � 最近はRでの大規模データ解析に興味がある.2007 2008 2009 2010 2011 データ解析 (金融工学) 今 日 大規模 の データ 発 解析 表 の Rの基礎とプログラミング技法 範 囲 Software for R Tips data analysis (Webサイト) RjpWiki CRANマニュアル (Webサイト) 6
  8. 8. アジェンダ1. 自己紹介2.クイズで議論! RのTips3. まとめ 7
  9. 9. 問題1【ファイルの読み込み】 8
  10. 10. � 自分で作成した関数を格納したファイルを読み 込んでいます.� 量が多くて大変です.� どうすれば良いでしょうか.> source("a.r")> source("b.r")> source("c.r")> source("d.r")...> source("z.r") 9
  11. 11. 【答え】読み込み用の関数を別途作成する 10
  12. 12. � 読み込み用関数を作成readfile.rreadfile <- function(){ fn.all <- c("a.r", "b.r", (中略), "z.r") for (fn in fn.all) { source(fn) cat(fn, "n") }}� 次のコマンドを実行> source("readfile.r")> readfile() 11
  13. 13. � 読み込み用関数を作成readfile.rreadfile <- function(){ fn.all <- c("a.r", "b.r", (中略), "z.r") for (fn in fn.all) { source(fn) cat(fn, "n") }}� 次のコマンドを実行> source("readfile.r"); readfile() 実は1行で書ける! 12
  14. 14. (ご参考)� 毎回,必ず読み込むファイルがある場合は,作 業フォルダ直下の.Rprofileファイルの.First関 数に記述しておくことも一つの手..Rprofile.First <- function(){ inputdir <- "C:UserssfchaoslibR" fn.all <- paste(inputdir, c("lib.r", "util.r")) for (fn in fn.all) { source(fn) cat(fn, "n") }}C:UserssfchaoslibRlib.rC:UserssfchaoslibRutil.r> 13
  15. 15. あまり派手にやると,不要な関数を読み込んで時間がかかるので おススメしません! 14
  16. 16. 第2問【データ・ファイルの管理】 15
  17. 17. � Rを使用してデータ解析を行っています.� 次のコードは,データをファイルから読み込み,データ の一部を変更し,ファイルに書き出しています.� 実行すると,望みどおりの動作をします.� このコードには問題はないでしょうか?> getwd()[1] "C:/Users/sfchaos/TokyoR/R_Tips(TokyoR#12)/work"> my.iris <- read.table("iris.csv", sep=",") # データの入力> my.iris[1:5, 1] <- 3> write.table(my.iris, "my_iris.csv", sep=",") # データの出力 16
  18. 18. 【答え】 問題あり!! 入力データ格納フォルダ, 作業フォルダ, 出力データ格納フォルダがすべて同じフォルダになっている 17
  19. 19. � データ解析は次のフローに従って行う. 入力データ 解析 出力データ 18
  20. 20. � フォルダも対応して別々に作ると良い. 入力データ 解析 出力データ data work output 19
  21. 21. � では,入力データ格納フォルダ("data"フォル ダ)のデータを作業フォルダで扱うには?� 2つの方法がある. 1)入力データ格納フォルダで作成したオブジェクトを 作業フォルダで読み込む 2)作業フォルダで,関数の引数に読み込む入力データ のファイル名を指定する 20
  22. 22. 1) 入力データ格納フォルダで作成したオブジェク トを作業フォルダで読み込む入力データ格納フォルダでの作業> getwd()[1] "C:/Users/sfchaos/TokyoR/R_Tips(TokyoR#12)/data"> my.iris <- read.table("iris.csv", sep=",")> assign("my.iris", my.iris, pos=1) # 現在の環境にオブジェクトを作成> quit # 保存してから終了する 21
  23. 23. 作業フォルダでの作業> getwd()[1] "C:/Users/sfchaos/TokyoR/R_Tips(TokyoR#12)/work"> attach("../data/.RData")> ls()character(0)> search()[1] ".GlobalEnv" "file:../data/.RData"...> ls(pos=2)[1] "my.iris" 22
  24. 24. 2) 作業フォルダで,関数の引数に読み込む入力  データのファイル名を指定するwork/hoge.rhoge <- function(fn="../data/my_iris.csv"){ my.iris <- read.table(fn, sep=",") (後略)}> source("hoge.r")> hoge() 23
  25. 25. データフォルダを複数作成する場合は,こうすると良いwork/hoge2.rhoge2 <- function(datadir="../data/", fn="my_iris.csv"){ my.iris <- read.table(paste(datadir, fn, sep=""), sep=",") (後略) 「入力データフォルダ名」と} 「入力データファイル名」を分離 24
  26. 26. 第3問【NA/NaN/Infの判定】 25
  27. 27. � データの中に存在するNAやNaNに加えて,Infも 調べようとしています.� ところが,is.na関数やis.nan関数を使っても Infは検出できません.� NA, NaNも調べられて,なおかつInfも調べるた めにはどうすれば良いでしょうか?> x[1] 1 5 NA 3 NaN 9 6 Inf> is.nan(x)[1] FALSE FALSE FALSE FALSE TRUE FALSE FALSE FALSE> is.na(x)[1] FALSE FALSE TRUE FALSE TRUE FALSE FALSE FALSE 26
  28. 28. 【答え】is.finite関数を使用する 27
  29. 29. > x[1] 1 5 NA 3 NaN 9 6 Inf> is.finite(x)[1] TRUE TRUE FALSE TRUE FALSE TRUE TRUE FALSE 28
  30. 30. 第4問【総称型関数】 29
  31. 31. � Rにも慣れてきて,パッケージの関数の中身を確 認したいと思うようになりました.� ところが,次の表示が出て中身が確認できませ ん.� 中身を確認する関数を調べるにはどうすれば良 いでしょうか?> install.packages("randomForest")> library(randomForest)> randomForestfunction (x, ...)UseMethod("randomForest")<environment: namespace:randomForest> 30
  32. 32. 【答え】methods関数で調べる 31
  33. 33. � 総称型関数とは?(plot関数の例)> x <- runif(10)> class(x)[1] "numeric"> print(x) [1] 0.03060976 0.78413098 0.79548343 0.15108456 0.70864539 0.10040559 [7] 0.18165933 0.90008356 0.46093800 0.52717448> y <- sample(1:10, 100, replace=TRUE)> y.tbl <- table(y)> class(y)[1] "table"> print(y.tbl) 1 2 3 4 5 6 7 8 9 1011 16 13 8 11 15 9 7 8 2 ベクトルでも行列でも 同じprint関数で表示できる! 32
  34. 34. print関数> printfunction (x, ...)UseMethod("print")<environment: namespace:base> 33
  35. 35. ベクトル用print関数> print.defaultfunction (x, digits = NULL, quote = TRUE, na.print = NULL, print.gap = NULL, right = FALSE, max = NULL, useSource = TRUE, ...){ noOpt <- missing(digits) && missing(quote) && missing(na.print) && missing(print.gap) && missing(right) && missing(max) && missing(useSource) && length(list(...)) == 0L .Internal(print.default(x, digits, quote, na.print, print.gap, right, max, useSource, noOpt))}<environment: namespace:base> 34
  36. 36. table用print関数> print.tablefunction (x, digits = getOption("digits"), quote = FALSE, na.print = "", zero.print = "0", justify = "none", ...){ xx <- format(unclass(x), digits = digits, justify = justify) if (any(ina <- is.na(x))) xx[ina] <- na.print if (zero.print != "0" && any(i0 <- !ina & x == 0) && all(x == round(x))) xx[i0] <- sub("0", zero.print, xx[i0]) if (is.numeric(x) || is.complex(x)) print(xx, quote = quote, right = TRUE, ...) else print(xx, quote = quote, ...) invisible(x)}<environment: namespace:base> 35
  37. 37. � 総称型関数はmethods関数で調べられる> methods(randomForest)[1] randomForest.default* randomForest.formula* Non-visible functions are asterisked 36
  38. 38. 第5問【総称型関数(続き)】 37
  39. 39. � 第4問で調べるべき関数が分かったので,中身を 表示させようとしました.� ところが,次の表示が出ます.� どうすれば良いでしょうか?> randomForest.default エラー: オブジェクト randomForest.default がありません> randomForest.formula エラー: オブジェクト randomForest.formula がありません 38
  40. 40. 【答え】 マスクされた関数の中身は, getFromNamespace関数,またはパッケージ名:::関数名で 表示する 39
  41. 41. � getFromNamespace関数> getFromNamespace("randomForest.default", "randomForest")function (x, y = NULL, xtest = NULL, ytest = NULL, ntree = 500, mtry = if (!is.null(y) && !is.factor(y)) max(floor(ncol(x)/3), 1) else floor(sqrt(ncol(x))), replace = TRUE, classwt = NULL, cutoff, strata, sampsize = if (replace) nrow(x) else ceiling(0.632 * nrow(x)), nodesize = if (!is.null(y) && !is.factor(y)) 5 else 1, maxnodes = NULL, importance = FALSE, localImp = FALSE, nPerm = 1, proximity, oob.prox = proximity, norm.votes = TRUE, do.trace = FALSE, keep.forest = !is.null(y) && is.null(xtest), corr.bias = FALSE, keep.inbag = FALSE, ...){ 中略}<environment: namespace:randomForest> 40
  42. 42. � パッケージ名:::関数名> randomForest:::randomForest.defaultfunction (x, y = NULL, xtest = NULL, ytest = NULL, ntree = 500, mtry = if (!is.null(y) && !is.factor(y)) max(floor(ncol(x)/3), 1) else floor(sqrt(ncol(x))), replace = TRUE, classwt = NULL, cutoff, strata, sampsize = if (replace) nrow(x) else ceiling(0.632 * nrow(x)), nodesize = if (!is.null(y) && !is.factor(y)) 5 else 1, maxnodes = NULL, importance = FALSE, localImp = FALSE, nPerm = 1, proximity, oob.prox = proximity, norm.votes = TRUE, do.trace = FALSE, keep.forest = !is.null(y) && is.null(xtest), corr.bias = FALSE, keep.inbag = FALSE, ...){ 中略}<environment: namespace:randomForest> 41
  43. 43. � そもそもrandomForest.default関数が randomForestパッケージにあることをどのよう に知ればよいか?> randomForestfunction (x, ...)UseMethod("randomForest")<environment: namespace:randomForest> 42
  44. 44. � 入っているパッケージが分からないときは?> getAnywhere("randomForest.default")A single object matching ‘randomForest.default’ was foundIt was found in the following places registered S3 method for randomForest from namespace randomForest namespace:randomForestwith valuefunction (x, y = NULL, xtest = NULL, ytest = NULL, ntree = 500, mtry = if (!is.null(y) && !is.factor(y)) max(floor(ncol(x)/3), 1) else floor(sqrt(ncol(x))), replace = TRUE, classwt = NULL, cutoff, strata, sampsize = if (replace) nrow(x) else ceiling(0.632 * nrow(x)), nodesize = if (!is.null(y) && !is.factor(y)) 5 else 1, maxnodes = NULL, importance = FALSE, localImp = FALSE, nPerm = 1, proximity, oob.prox = proximity, norm.votes = TRUE, do.trace = FALSE, keep.forest = !is.null(y) && is.null(xtest), corr.bias = FALSE, keep.inbag = FALSE, ...){ 中略}<environment: namespace:randomForest> 43
  45. 45. 第6問【デバッグ】 44
  46. 46. � パッケージをインストールして,関数がどのよ うな動きをするか確めます.� インプットとアウトプットだけでなく,途中で どのような処理をしているか知りたくなりまし た.� しかし,パッケージの関数の中に直接cat関数や print関数を埋め込むことは出来ません.� 仕方ないので,パッケージの関数をコピーして, catやprintを埋め込みました.� 何か問題はあるでしょうか? 45
  47. 47. work/my_randomForest.rmy.randomForest <- function (x, ...)UseMethod("my.randomForest")my.randomForest.default <- functionfunction (x, y = NULL, xtest = NULL, ytest = NULL, ntree = 500, mtry = if (!is.null(y) && !is.factor(y)) max(floor(ncol(x)/3), 1) else floor(sqrt(ncol(x))), replace = TRUE, classwt = NULL, cutoff, strata, sampsize = if (replace) nrow(x) else ceiling(0.632 * nrow(x)), nodesize = if (!is.null(y) && !is.factor(y)) 5 else 1, maxnodes = NULL, importance = FALSE, localImp = FALSE, nPerm = 1, proximity, oob.prox = proximity, norm.votes = TRUE, do.trace = FALSE, keep.forest = !is.null(y) && is.null(xtest), corr.bias = FALSE, keep.inbag = FALSE, ...){ addclass <- is.null(y) cat(addclass, "n") classRF <- addclass || is.factor(y) print(classRF) if (!classRF && length(unique(y)) <= 5) { warning("The response has five or fewer unique values. Are you sure you want todo regression?") } (中略)} 46
  48. 48. 【答え】関数の中身を調べたいときは, デバッグ用の関数を使う 47
  49. 49. � デバッグモードの設定> debug(randomForest:::randomForest.default)� デバッグモードでの実行> randomForest(iris[, -5])Browse[2]> debug: addclass <- is.null(y)Browse[2]> ndebug: classRF <- addclass || is.factor(y)Browse[2]> addclass[1] TRUE 48
  50. 50. アジェンダ1. 自己紹介2.クイズで議論! RのTips3. まとめ 49
  51. 51. � Rは使いやすい統計ツールですが,効率的に使う ためのテクニックがいろいろとあります.� 自分で試行錯誤したり,RjpWikiなどで調べるこ とが「自分にとって使いやすい」Tipsをためる ことにつながります.� Rに少し慣れてきたら,「Rの基礎とプログラミ ング技法」は必ず読みましょう! 50

×