目次 †
概要 †R言語は、統計解析向けのプログラミング言語及びその開発実行環境。 インストール †以下の URLからインストーラをダウンロードしてインストール 基本操作 †開始と終了 †Rがインストールされている環境で r を入力すれば、R がインタラクティブモードで起動する。 r R version 3.5.2 (2018-12-20) -- "Eggshell Igloo" Copyright (C) 2018 The R Foundation for Statistical Computing . . . 'demo()' と入力すればデモをみることができます。 'help()' とすればオンラインヘルプが出ます。 'help.start()' で HTML ブラウザによるヘルプがみられます。 'q()' と入力すれば R を終了します。 > 終了は q() > q() Save workspace image? [y/n/c]: n ※ --save または --no-save オプション付きで起動した場合は、終了時の確認メッセージは表示されない。 ヘルプの表示方法 †?コマンド名 または help(コマンド名) でコマンドのヘルプを表示する事ができる。 例) > ?read.table read.table package:utils R Documentation . . Usage: read.table(file, header = FALSE, sep = "", quote = "\"'", dec = ".", numerals = c("allow.loss", "warn.loss", "no.loss"), row.names, col.names, as.is = !stringsAsFactors, na.strings = "NA", colClasses = NA, nrows = -1, skip = 0, check.names = TRUE, fill = !blank.lines.skip, strip.white = FALSE, blank.lines.skip = TRUE, . . 変数への代入 †変数への代入は <- または -> で行う。 > x <- c(1:5) > x [1] 1 2 3 4 5 ()で囲むと変数に代入すると同時に内容を表示する事ができる。 > (x <- c(1:5)) [1] 1 2 3 4 5 複数の変数に代入する事も可能 > x <- y <- 1:5 > x [1] 1 2 3 4 5 > y [1] 1 2 3 4 5 左辺と右辺は入れ替える事も可能 > 1:5 -> x -> y > x [1] 1 2 3 4 5 > y [1] 1 2 3 4 5 グローバル変数への代入 †グローバル変数への代入は <<- で行なう。 > count <- 0 > mycount <- function(num){ + count <<- count + num + } > mycount(1) > mycount(2) > mycount(3) > count [1] 6 連続した値の生成 †n:m と記述する事で連続した値を生成する事ができる。 > 1:5 [1] 1 2 3 4 5 開始値, 終了値, 増分 を指定して値を生成する場合は seq を使用する。 > seq(1, 5, 2) [1] 1 3 5 繰り返し値の生成 †任意の値をN個分繰り返すには rep を使用する。 > rep(1, 5) [1] 1 1 1 1 1 値には ベクトルを指定する事もできる。 > rep(1:3, 5) [1] 1 2 3 1 2 3 1 2 3 1 2 3 1 2 3 定義済みの変数一覧を表示する †定義した全ての変数の一覧を ls() で確認する事ができる。 > x <- 1:10 > y <- 101:110 > ls() [1] "x" "y" 使わない変数を消す †rm で定義した変数を削除する事ができる。 > x <- 1:10 > y <- 101:110 > ls() [1] "x" "y" > rm(y) > ls() [1] "x" rm の 名前付き引数 list に変数名の一覧を指定して削除する事もできる。 > x <- 1:10 > y <- 101:110 > ls() [1] "x" "y" > rm(list=ls()) > ls() character(0) 外部スクリプトの読み込み †別ファイルに保存したスクリプトを読み込むには source を使用する。 test.R x = c(1:5) 実行例 > source("test.R") > x [1] 1 2 3 4 5 ワークスペースの保存 †Rでは作業中のワークスペースの状態をワークスペースに保存しておき、後から復元する事ができる。 変数 x, y, z を定義してRを終了(確認で y を入力) R > x <- 1:10 > y <- 101:110 > z <- 201:210 > q() Save workspace image? [y/n/c]: y 再開 R . . [以前にセーブされたワークスペースを復帰します] > ls() [1] "x" "y" "z" R を --save または --no-save オプション付きで起動した場合は、Rの終了時に確認メッセージは表示されない。 尚、変数 及び 履歴情報は作業ディレクトリ配下の .RData 及び .Rhistory というファイルに保存されている。 コマンドラインから R のスクリプトを実行する †test.R x <- 1:10 cat(x) 実行 rscript test.R 1 2 3 4 5 6 7 8 9 10 コマンドライン引数を受け取る †commandArgs(trailingOnly=T) でコマンドライン引数を受け取る事ができる。 get_args.R args <- commandArgs(trailingOnly=T) for (i in seq(length(args))) { arg <- args[i] cat("arg", i, " = ", arg, "\n", sep="") } 実行結果 rscript get_args.R ABC 123 arg1 = ABC arg2 = 123 定数など †以下のビルトイン定数やオブジェクトが使用できる。
> NULL NULL > NaN [1] NaN > T [1] TRUE > F [1] FALSE > LETTERS [1] "A" "B" "C" "D" "E" "F" "G" "H" "I" "J" "K" "L" "M" "N" "O" "P" "Q" "R" "S" "T" "U" "V" "W" "X" "Y" "Z" > letters [1] "a" "b" "c" "d" "e" "f" "g" "h" "i" "j" "k" "l" "m" "n" "o" "p" "q" "r" "s" "t" "u" "v" "w" "x" "y" "z" > month.abb [1] "Jan" "Feb" "Mar" "Apr" "May" "Jun" "Jul" "Aug" "Sep" "Oct" "Nov" "Dec" > month.name [1] "January" "February" "March" "April" "May" "June" "July" "August" "September" [10] "October" "November" "December" > pi [1] 3.141593 オブジェクト内容の表示 †変数名のタイプによる表示 †> x <- 1:10 > x [1] 1 2 3 4 5 6 7 8 9 10 print による表示 †> x <- 1:10 > print(x) [1] 1 2 3 4 5 6 7 8 9 10 sprintf †書式付きでオブジェクトを表示する場合には sprint を使用する。 > sprintf("%3.2f", 123.456) [1] "123.46" cat †cat を使用すれば文字列をダブルクォーテーションなしで表示できる。 > str1 = "ABCDEFG" > cat(str1) ABCDEFG str †str を使用すると、オブジェクトの内容をデータ型などの情報付きで表示できる。 > str1 = "123" > str(str1) chr "123" 基本的な関数 †サイズを調べる †length、ncol、nrow でベクトルや行列等の長さを調べる事ができる。 > x <- matrix(1:20, ncol = 5) > x [,1] [,2] [,3] [,4] [,5] [1,] 1 5 9 13 17 [2,] 2 6 10 14 18 [3,] 3 7 11 15 19 [4,] 4 8 12 16 20 > length(x) # 全体のサイズ [1] 20 > ncol(x) # 列数 [1] 5 > nrow(x) # 行数 [1] 4 > nchar("12345678") # 文字列の長さ [1] 8 合計/最小/最大/平均/中央値/分散/標準偏差 †> x <- c(1, 2, 3, 4, 5) > # 合計 > sum(x) [1] 15 > # 最小 > min(x) [1] 1 > # 最大 > max(x) [1] 5 > # 平均 > mean(x) [1] 3 > # 中央値 > median(x) [1] 3 > # 分散 > var(x) [1] 2.5 > # 標準偏差 > sd(x) [1] 1.581139 行/列ごとの統計値 †x <- matrix(1:9, nrow=3, byrow=T) # 行ごとの合計 rowSums(x) # 列毎の合計 colSums(x) # 行ごとの平均 rowMeans(x) # 列ごとの平均 colMeans(x) # 行ごとの中央値 > apply(x, 1, median) [1] 2 5 8 # 行ごとの標準偏差 > apply(x, 1, sd) [1] 1 1 1 ※専用の関数がない場合は、apply を使用して求める事ができる。 summary による列情報の概要表示 †summary で列毎の概要を表示する事ができる。 > x <- matrix(1:20, ncol = 5) > colnames(x) <- paste("col", 1:ncol(x), sep = "") > rownames(x) <- paste("No", 1:nrow(x), sep = "") > x col1 col2 col3 col4 col5 No1 1 5 9 13 17 No2 2 6 10 14 18 No3 3 7 11 15 19 No4 4 8 12 16 20 > summary(x) col1 col2 col3 col4 col5 Min. :1.00 Min. :5.00 Min. : 9.00 Min. :13.00 Min. :17.00 1st Qu.:1.75 1st Qu.:5.75 1st Qu.: 9.75 1st Qu.:13.75 1st Qu.:17.75 Median :2.50 Median :6.50 Median :10.50 Median :14.50 Median :18.50 Mean :2.50 Mean :6.50 Mean :10.50 Mean :14.50 Mean :18.50 3rd Qu.:3.25 3rd Qu.:7.25 3rd Qu.:11.25 3rd Qu.:15.25 3rd Qu.:19.25 Max. :4.00 Max. :8.00 Max. :12.00 Max. :16.00 Max. :20.00 実行時間の計測 †処理制御 †条件分岐 †> x <- 10 > if (x == 5) { + cat("x == 5") + } else if (x < 8) { + cat("x < 8") + } else { + cat("other") + } other forループ †繰り返し処理には for文が使用できる。 > for (i in 1:5) { + print(i) + } [1] 1 [1] 2 [1] 3 [1] 4 [1] 5 whileループ †while ループを使用する事もできる。 > i <- 1 > while(i <= 10) { + cat(sprintf("i = %d\n", i)) + i <- i + 1 + } i = 1 i = 2 i = 3 i = 4 i = 5 i = 6 i = 7 i = 8 i = 9 i = 10 switch文 †TODO:
関数の定義 †関数名 <- function(引数,...) で関数を定義する事ができる。 > myfunc <- function(x) { + return (x*2) + } > > myfunc(2) [1] 4 > myfunc(10) [1] 100 パイプの使用 †シェル等で使用する | と同等の機能は「%>%」 で実現できる。 > # dplyr のインストール(グループ化で使用する) > install.packages("dplyr") > > # dplyrの読み込み > library(dplyr) > sex <- c("W", "M", "M", "M", "W", "W", "W", "W", "M", "W") > state <- c("Osaka", "Tokyo", "Osaka", "Osaka", "Nagoya", "Osaka", "Tokyo", "Tokyo", "Nagoya", "Tokyo") > height <- c(170.5, 175.4, 171.2, 173.6, 169.8, 165.2, 178.1, 165.5, 173.2, 172.9) > パイプを使用して都道府県毎にグループ化 > data.frame(Sex=sex, State=state, Height=height) %>% dplyr::group_by(State) %>% dplyr::summarise(Count = n()) # A tibble: 3 x 2 State Count 例外処理 †> tryCatch({ + print("start!") + rbind(x, c(1:10)) + print("end!") + } + , warning = function(e) { + print("warning") + print(e) + } + , error = function(e) { + print("error!") + print(e) + } + , finally = { + print("finally!") + }) [1] "start!" [1] "error!" <simpleError in rbind(x, c(1:10)): オブジェクト 'x' がありません > [1] "finally!" メッセージを表示する †いろいろやり方はあるが、プログラムの進捗状況などを表示する際には message や warning が使用できる。 > cat("cat!", "\n") cat! > print("print!") [1] "print!" > message("message!") message! > warning("warning!") 警告メッセージ: warning! メッセージの表示を抑制する †suppressMessages で message の表示を抑制する事ができる。 > suppressMessages({ + message("test message") + warning("test warning") + }) 警告メッセージ: withCallingHandlers(expr, message = function(c) invokeRestart("muffleMessage")) で: test warning }) suppressWarnings で warning の表示を抑制する事ができる。 > suppressWarnings({ + message("test message") + warning("test warning") + }) test message cat や print の表示を抑制する場合は、sink や capture.output で出力をファイルに吐く。 sink("dummy.txt") print("test print!") cat("test cat!", "\n") sink() capture.output( cat("test cat!", "\n"), print("test print!"), file = "caputure.txt", type = c("output", "message") ) 文字列の操作 †文字列の結合 †> paste("abc", "def", sep="") [1] "abcdef" 文字列の分割 †strsplit で文字列を分割する事ができる。 > text <- "abc,def,ghi" > res <- strsplit(text, ",") > res [[1]] [1] "abc" "def" "ghi" > res[[1]] [1] "abc" "def" "ghi" > res[[1]][1] [1] "abc" > unlist(res)[1] [1] "abc" 文字列の切り出し †substr で文字列を部分的に切り出す事が可能。 > substr("1234567890", 2, 3) [1] "23" > substr(c("1234567890", "abcdefghijklmn"), 2, 3) [1] "23" "bc" 文字列の置換 †sub または gsub で文字列の置換を行う事ができる。 > sub("l", "L", c("Hello R!", "Hello Python!")) # マッチする最初の1文字を置換 [1] "HeLlo R!" "HeLlo Python!" > gsub("l", "L", c("Hello R!", "Hello Python!")) # マッチする全ての文字を置換 [1] "HeLLo R!" "HeLLo Python!" > gsub("[^a-zA-Z ]", "#", c("Hello R!", "Hello Python!")) # 正規表現で置換 [1] "Hello R#" "Hello Python#" 文字列の長さを調べる †nchar > length("abc") # lengthでは正しい長さは得られない [1] 1 > nchar("abc") # nchar だと正しい長さが得られる [1] 3 文字列の大文字/小文字を変換する †大文字に変換 > toupper("abc") [1] "ABC" > toupper(c("abc", "def")) [1] "ABC" "DEF" 小文字に変換 > tolower("ABC") [1] "abc" > tolower(c("ABC", "DEF")) [1] "abc" "def" ベクトルの操作 †ベクトルの生成 †c() でベクトルの生成を行う事ができる。 > x <- c(100,200,300) > x [1] 100 200 300 連続した値のベクトルであれば n:m でも生成可能。 > x <- 1:5 > x [1] 1 2 3 4 5 他にファイルからデータを読み込んでデータフレームを生成する事も可能。( CSVファイルの入出力 を参照 ) ベクトルの要素へのアクセス †要素番号を指定して特定の要素にアクセスする事ができる。 > x <- 10:20 > x [1] 10 11 12 13 14 15 16 17 18 19 20 > x[2] <- 99 > x [1] 10 99 12 13 14 15 16 17 18 19 20 ベクトルの特定の値を書き換える †要素番号を指定して特定の要素にアクセスする事ができる。 > x <- 10:20 > x [1] 10 11 12 13 14 15 16 17 18 19 20 > x[x == 15] <- 999 > x [1] 10 11 12 13 14 999 16 17 18 19 20 上記を分けて書くと以下のようになる。 > x <- 10:20 > x [1] 10 11 12 13 14 15 16 17 18 19 20 > condition <- x == 15 > condition [1] FALSE FALSE FALSE FALSE FALSE TRUE FALSE FALSE FALSE FALSE FALSE > x[condition] <- 999 > x [1] 10 11 12 13 14 999 16 17 18 19 20 ベクトルの結合 †c() でベクトルを結合した別のベクトルを得る事ができる。 > x <- 1:10 > y <- 11:20 > z <- c(x, y) > x [1] 1 2 3 4 5 6 7 8 9 10 > y [1] 11 12 13 14 15 16 17 18 19 20 > z [1] 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 ベクトルの要素の追加 †append を使用するとベクトルに要素を追加した別のベクトルを得る事ができる。 > x <- 1:10 > y <- append(x, 101:105) > x [1] 1 2 3 4 5 6 7 8 9 10 # x 自体の内容は変わらない > y [1] 1 2 3 4 5 6 7 8 9 10 101 102 103 104 105 行列の操作 †行列の生成 †matrix で行列を生成する事ができる。 > matrix(1:9, nrow=3, ncol=3) [,1] [,2] [,3] [1,] 1 4 7 [2,] 2 5 8 [3,] 3 6 9 > matrix(1:9, nrow=3, ncol=3, byrow=T) [,1] [,2] [,3] [1,] 1 2 3 [2,] 4 5 6 [3,] 7 8 9 行数/列数の確認 †> x <- matrix(1:10, nrow=2, ncol=5, byrow=T) > nrow(x) # 行数の確認 [1] 2 > ncol(x) # 列数の確認 [1] 5 > dim(x) # 行数、列数の確認 [1] 2 5 列ラベル/行ラベルの付与 †colnames、rownames で列 及び 行にラベルを付与する事ができ、 > x <- matrix(1:20, ncol=5) > x [,1] [,2] [,3] [,4] [,5] [1,] 1 5 9 13 17 [2,] 2 6 10 14 18 [3,] 3 7 11 15 19 [4,] 4 8 12 16 20 > colnames(x) <- paste("col", 1:ncol(x), sep="") # 列にラベルを付与 > x col1 col2 col3 col4 col5 [1,] 1 5 9 13 17 [2,] 2 6 10 14 18 [3,] 3 7 11 15 19 [4,] 4 8 12 16 20 > rownames(x) <- paste("row", 1:nrow(x), sep="") # 行にラベルを付与 > x col1 col2 col3 col4 col5 row1 1 5 9 13 17 row2 2 6 10 14 18 row3 3 7 11 15 19 row4 4 8 12 16 20 > x["row3","col3"] # 行 及び 列ラベルを指定してアクセス [1] 11 > x["row3",] # 行ラベルのみを指定してアクセス col1 col2 col3 col4 col5 3 7 11 15 19 > x[,"col5"] # 列ラベルのみを指定してアクセス row1 row2 row3 row4 17 18 19 20 行列の入れ替え †t() で行列を入れ替える事ができる。 > x <- matrix(1:9, nrow=3, ncol=3) > x [,1] [,2] [,3] [1,] 1 4 7 [2,] 2 5 8 [3,] 3 6 9 > t(x) [,1] [,2] [,3] [1,] 1 2 3 [2,] 4 5 6 [3,] 7 8 9 行列の要素へのアクセス †行列の各要素へは [行No, 列No] でアクセス可能。 > x <- matrix(1:9, nrow=3, ncol=3, byrow=T) > x [,1] [,2] [,3] [1,] 1 2 3 [2,] 4 5 6 [3,] 7 8 9 > x[2,2] [1] 5 > x[2,2] <- 10 > x [,1] [,2] [,3] [1,] 1 2 3 [2,] 4 10 6 [3,] 7 8 9 以下のように、特定の値を変更する事も可能。 > x <- matrix(1:9, nrow=3, ncol=3, byrow=T) > x [,1] [,2] [,3] [1,] 1 2 3 [2,] 4 5 6 [3,] 7 8 9 > x[x == 1 | x == 8] <- 999 > x [,1] [,2] [,3] [1,] 999 2 3 [2,] 4 5 6 [3,] 7 999 9 以下の例では偶数値を "even!" に書き換えている。 > x <- matrix(1:9, nrow=3, ncol=3, byrow=T) > x [,1] [,2] [,3] [1,] 1 2 3 [2,] 4 5 6 [3,] 7 8 9 > x[x %% 2 == 0] <- "even!" > x [,1] [,2] [,3] [1,] "1" "even!" "3" [2,] "even!" "5" "even!" [3,] "7" "even!" "9" pandasのデータフレームと同じ様に Bool値のリストを作って真となるの要素を書き換える事も可能。 > x <- matrix(1:9, nrow=3, ncol=3, byrow=T) > x [,1] [,2] [,3] [1,] 1 2 3 [2,] 4 5 6 [3,] 7 8 9 > x[x %% 2 == 0 -> even] [1] 4 2 8 6 > even [,1] [,2] [,3] [1,] FALSE TRUE FALSE [2,] TRUE FALSE TRUE [3,] FALSE TRUE FALSE > x[even] <- "even!" > x [,1] [,2] [,3] [1,] "1" "even!" "3" [2,] "even!" "5" "even!" [3,] "7" "even!" "9" 行列の結合 †rbind または cbind で行列を結合する事ができる。 > x = matrix(1:9,ncol = 3, nrow =3) > y = matrix(11:13, ncol = 3, nrow =1) > z = matrix(21:23, ncol = 1, nrow =3) > x [,1] [,2] [,3] [1,] 1 4 7 [2,] 2 5 8 [3,] 3 6 9 > y [,1] [,2] [,3] [1,] 11 12 13 > z [,1] [1,] 21 [2,] 22 [3,] 23 > rbind(x, y) [,1] [,2] [,3] [1,] 1 4 7 [2,] 2 5 8 [3,] 3 6 9 [4,] 11 12 13 > cbind(x, z) [,1] [,2] [,3] [,4] [1,] 1 4 7 21 [2,] 2 5 8 22 [3,] 3 6 9 23 行列の演算 †行列の和、差 > x <- matrix(1:4, 2, 2, byrow=T) > x [,1] [,2] [1,] 1 2 [2,] 3 4 > y <- matrix(1:4, 2, 2, byrow=T) > y [,1] [,2] [1,] 1 2 [2,] 3 4 > x + y # 行列の和 [,1] [,2] [1,] 2 4 [2,] 6 8 > x - y # 行列の差 [,1] [,2] [1,] 0 0 [2,] 0 0 行列の積 > x <- matrix(1:6, 2, 3, byrow=T) > x [,1] [,2] [,3] [1,] 1 2 3 [2,] 4 5 6 > y <- matrix(1:6, 3, 2, byrow=T) > y [,1] [,2] [1,] 1 2 [2,] 3 4 [3,] 5 6 > x %*% y # 行列積は %*% で行う( x * y だと要素毎の乗算になってしまう ) [,1] [,2] [1,] 22 28 [2,] 49 64 ※ numpyでの演算結果 とも一致する。 リストの操作 †ベクトルや行列などの異なる構造のデータを集めて 1 個のオブジェクトに纏める場合にはリストを使用する。 リストの生成 †> x <- 1:10 > y <- 101:110 > list(x, y) [[1]] [1] 1 2 3 4 5 6 7 8 9 10 [[2]] [1] 101 102 103 104 105 106 107 108 109 110 リストの要素へのアクセス †リストの要素には [要素番号] または [[要素番号]] でアクセスする事ができる。 > l = list(1,2,3) > l[1] [[1]] [1] 1 > l[[1]] [1] 1 リストをベクトルに変換する †unlist でリストをベクトルに変換する事ができる。 > l <- list(1,2,3) > l [[1]] [1] 1 [[2]] [1] 2 [[3]] [1] 3 > unlist(l) [1] 1 2 3 データフレームの操作 †データフレームを使用すると異なる型のデータをまとめて1 つの変数として持つ事ができる。 データフレームの生成 †データフレームは data.frame(列名=ベクトル, 列名=ベクトル, ... ) の形式で生成する。 > # 行ラベル > dates <- c("2018-06","2018-07","2018-08","2018-09","2018-10","2018-11","2018-12") > > # 以下列データ > chrome <- c(41.96, 41.9, 42.54, 41.18, 43.11, 44.28, 44.47) > safari <- c(31.83, 32.29, 31.91, 34.45, 33.01, 32.54, 31.96) > ie <- c(11.5, 11.13, 11.15, 10.43, 10.2, 9.49, 9.21) > firefox <- c(6.63, 6.43, 6.44, 6.14, 6.2, 6.31, 6.81) > edge <- c(4.29, 4.26, 4.23, 4.36, 4.23, 4.14, 4.0) > > # データフレームの生成 > x = data.frame(Chrome=chrome, Safari=safari, IE=ie, Firefox=firefox, Edge=edge) > > # 行ラベルを付与 > rownames(x) <- dates > x Chrome Safari IE Firefox Edge 2018-06 41.96 31.83 11.50 6.63 4.29 2018-07 41.90 32.29 11.13 6.43 4.26 2018-08 42.54 31.91 11.15 6.44 4.23 2018-09 41.18 34.45 10.43 6.14 4.36 2018-10 43.11 33.01 10.20 6.20 4.23 2018-11 44.28 32.54 9.49 6.31 4.14 2018-12 44.47 31.96 9.21 6.81 4.00 データフレームを行列に変換する †as.matrix による変換 > as.matrix(x) Chrome Safari IE Firefox Edge 2018-06 41.96 31.83 11.50 6.63 4.29 2018-07 41.90 32.29 11.13 6.43 4.26 2018-08 42.54 31.91 11.15 6.44 4.23 2018-09 41.18 34.45 10.43 6.14 4.36 2018-10 43.11 33.01 10.20 6.20 4.23 2018-11 44.28 32.54 9.49 6.31 4.14 2018-12 44.47 31.96 9.21 6.81 4.00 さらに matrix を噛ましてラベルを落とす > matrix(as.matrix(x), nrow(x), ncol(x)) [,1] [,2] [,3] [,4] [,5] [1,] 41.96 31.83 11.50 6.63 4.29 [2,] 41.90 32.29 11.13 6.43 4.26 [3,] 42.54 31.91 11.15 6.44 4.23 [4,] 41.18 34.45 10.43 6.14 4.36 [5,] 43.11 33.01 10.20 6.20 4.23 [6,] 44.28 32.54 9.49 6.31 4.14 [7,] 44.47 31.96 9.21 6.81 4.00 colnames、rownames に NULL を設定して名前を落とす > y <- as.matrix(x) > y Chrome Safari IE Firefox Edge 2018-06 41.96 31.83 11.50 6.63 4.29 2018-07 41.90 32.29 11.13 6.43 4.26 2018-08 42.54 31.91 11.15 6.44 4.23 2018-09 41.18 34.45 10.43 6.14 4.36 2018-10 43.11 33.01 10.20 6.20 4.23 2018-11 44.28 32.54 9.49 6.31 4.14 2018-12 44.47 31.96 9.21 6.81 4.00 > colnames(y) <- NULL > rownames(y) <- NULL > y [,1] [,2] [,3] [,4] [,5] [1,] 41.96 31.83 11.50 6.63 4.29 [2,] 41.90 32.29 11.13 6.43 4.26 [3,] 42.54 31.91 11.15 6.44 4.23 [4,] 41.18 34.45 10.43 6.14 4.36 [5,] 43.11 33.01 10.20 6.20 4.23 [6,] 44.28 32.54 9.49 6.31 4.14 [7,] 44.47 31.96 9.21 6.81 4.00 データフレームの列にアクセスする †変数名$列名 とする事でデータフレームの特定の列にアクセスできる。 > df = read.table("browser-JP.csv", sep=",", header=T, row.names="Date") > df Chrome Safari IE Firefox Edge Android 2018-06 41.96 31.83 11.50 6.63 4.29 0.97 2018-07 41.90 32.29 11.13 6.43 4.26 0.90 2018-08 42.54 31.91 11.15 6.44 4.23 0.90 2018-09 41.18 34.45 10.43 6.14 4.36 0.78 2018-10 43.11 33.01 10.20 6.20 4.23 0.69 2018-11 44.28 32.54 9.49 6.31 4.14 0.69 2018-12 44.47 31.96 9.21 6.81 4.00 0.74 > df$Chrome [1] 41.96 41.90 42.54 41.18 43.11 44.28 44.47 データフレームに列を追加する †元のデータフレームの内容を書き換える場合は、変数名$列名 <- ベクトル または 「変数名[,"列名"] <- ベクトル で追加する事ができる。 > df = read.table("browser-JP.csv", sep=",", header=T, row.names="Date") > df$Desc <- rownames(df) > df Chrome Safari IE Firefox Edge Android Desc 2018-06 41.96 31.83 11.50 6.63 4.29 0.97 2018-06 2018-07 41.90 32.29 11.13 6.43 4.26 0.90 2018-07 2018-08 42.54 31.91 11.15 6.44 4.23 0.90 2018-08 2018-09 41.18 34.45 10.43 6.14 4.36 0.78 2018-09 2018-10 43.11 33.01 10.20 6.20 4.23 0.69 2018-10 2018-11 44.28 32.54 9.49 6.31 4.14 0.69 2018-11 2018-12 44.47 31.96 9.21 6.81 4.00 0.74 2018-12 transform を使用するとデータフレームに新たな列を追加した別のデータフレームを得る事ができる。 > df = read.table("browser-JP.csv", sep=",", header=T, row.names="Date") > df Chrome Safari IE Firefox Edge Android 2018-06 41.96 31.83 11.50 6.63 4.29 0.97 2018-07 41.90 32.29 11.13 6.43 4.26 0.90 2018-08 42.54 31.91 11.15 6.44 4.23 0.90 2018-09 41.18 34.45 10.43 6.14 4.36 0.78 2018-10 43.11 33.01 10.20 6.20 4.23 0.69 2018-11 44.28 32.54 9.49 6.31 4.14 0.69 2018-12 44.47 31.96 9.21 6.81 4.00 0.74 > desc = rownames(df) > desc [1] "2018-06" "2018-07" "2018-08" "2018-09" "2018-10" "2018-11" "2018-12" > df2 = transform(df, Desc=desc) > df2 Chrome Safari IE Firefox Edge Android Desc 2018-06 41.96 31.83 11.50 6.63 4.29 0.97 2018-06 2018-07 41.90 32.29 11.13 6.43 4.26 0.90 2018-07 2018-08 42.54 31.91 11.15 6.44 4.23 0.90 2018-08 2018-09 41.18 34.45 10.43 6.14 4.36 0.78 2018-09 2018-10 43.11 33.01 10.20 6.20 4.23 0.69 2018-10 2018-11 44.28 32.54 9.49 6.31 4.14 0.69 2018-11 2018-12 44.47 31.96 9.21 6.81 4.00 0.74 2018-12 データフレームの列を削除する †列の削除にはいくつか方法がある。 ・データフレーム名 <- データフレーム名[, -列番号] df <- data.frame( col1=c(1:10), col2=c(21:30), col3=c(31:40), col4=c(41:50), col5=c(51:60), col6=c(61:70), col7=c(71:80), col8=c(81:90), col9=c(91:100), col10=c(101:110), row.names = paste("ROW", seq(10), sep="") ) print(df) # col1を削除 df <- df[, -1] # col3を削除 df$col3 <- NULL # col5、col7を削除 df[, c("col5","col7")] <- NULL print(df) 結果 col1 col2 col3 col4 col5 col6 col7 col8 col9 col10 ROW1 1 21 31 41 51 61 71 81 91 101 ROW2 2 22 32 42 52 62 72 82 92 102 ROW3 3 23 33 43 53 63 73 83 93 103 ROW4 4 24 34 44 54 64 74 84 94 104 ROW5 5 25 35 45 55 65 75 85 95 105 ROW6 6 26 36 46 56 66 76 86 96 106 ROW7 7 27 37 47 57 67 77 87 97 107 ROW8 8 28 38 48 58 68 78 88 98 108 ROW9 9 29 39 49 59 69 79 89 99 109 ROW10 10 30 40 50 60 70 80 90 100 110 col2 col4 col6 col8 col9 col10 ROW1 21 41 61 81 91 101 ROW2 22 42 62 82 92 102 ROW3 23 43 63 83 93 103 ROW4 24 44 64 84 94 104 ROW5 25 45 65 85 95 105 ROW6 26 46 66 86 96 106 ROW7 27 47 67 87 97 107 ROW8 28 48 68 88 98 108 ROW9 29 49 69 89 99 109 ROW10 30 50 70 90 100 110 データフレームに行を追加する †変数名[行ラベル名,] <- データ で行データを追加できる。 > df = read.table("browser-JP.csv", sep=",", header=T, row.names="Date") > df Chrome Safari IE Firefox Edge Android 2018-06 41.96 31.83 11.50 6.63 4.29 0.97 2018-07 41.90 32.29 11.13 6.43 4.26 0.90 2018-08 42.54 31.91 11.15 6.44 4.23 0.90 2018-09 41.18 34.45 10.43 6.14 4.36 0.78 2018-10 43.11 33.01 10.20 6.20 4.23 0.69 2018-11 44.28 32.54 9.49 6.31 4.14 0.69 2018-12 44.47 31.96 9.21 6.81 4.00 0.74 > df["2019-01",] <- c(42.9, 33.84, 9.45, 6.01, 4.16, 0.7) > df Chrome Safari IE Firefox Edge Android 2018-06 41.96 31.83 11.50 6.63 4.29 0.97 2018-07 41.90 32.29 11.13 6.43 4.26 0.90 2018-08 42.54 31.91 11.15 6.44 4.23 0.90 2018-09 41.18 34.45 10.43 6.14 4.36 0.78 2018-10 43.11 33.01 10.20 6.20 4.23 0.69 2018-11 44.28 32.54 9.49 6.31 4.14 0.69 2018-12 44.47 31.96 9.21 6.81 4.00 0.74 2019-01 42.90 33.84 9.45 6.01 4.16 0.70 ラベル名が不要(もしくは連番) の場合は、変数名[nrow(変数名)+1,] <- データ でOK。 > df = read.table("browser-JP.csv", sep=",", header=T, row.names="Date") > rownames(df) <- NULL # 行ラベルを落とす > df Chrome Safari IE Firefox Edge Android 1 41.96 31.83 11.50 6.63 4.29 0.97 2 41.90 32.29 11.13 6.43 4.26 0.90 3 42.54 31.91 11.15 6.44 4.23 0.90 4 41.18 34.45 10.43 6.14 4.36 0.78 5 43.11 33.01 10.20 6.20 4.23 0.69 6 44.28 32.54 9.49 6.31 4.14 0.69 7 44.47 31.96 9.21 6.81 4.00 0.74 > df[nrow(df)+1,] <- c(42.9, 33.84, 9.45, 6.01, 4.16, 0.7) > df Chrome Safari IE Firefox Edge Android 1 41.96 31.83 11.50 6.63 4.29 0.97 2 41.90 32.29 11.13 6.43 4.26 0.90 3 42.54 31.91 11.15 6.44 4.23 0.90 4 41.18 34.45 10.43 6.14 4.36 0.78 5 43.11 33.01 10.20 6.20 4.23 0.69 6 44.28 32.54 9.49 6.31 4.14 0.69 7 44.47 31.96 9.21 6.81 4.00 0.74 8 42.90 33.84 9.45 6.01 4.16 0.70 データフレームの行を削除する †df <- data.frame( col1=c(1:10), col2=c(21:30), col3=c(31:40), col4=c(41:50), col5=c(51:60), col6=c(61:70), col7=c(71:80), col8=c(81:90), col9=c(91:100), col10=c(101:110), row.names = paste("ROW", seq(10), sep="") ) print(df) # 1行目を削除 df <- df[-1,] # 行名を指定して削除 df <- df[-which(rownames(df) == "ROW5"),] print(df) 結果 col1 col2 col3 col4 col5 col6 col7 col8 col9 col10 ROW1 1 21 31 41 51 61 71 81 91 101 ROW2 2 22 32 42 52 62 72 82 92 102 ROW3 3 23 33 43 53 63 73 83 93 103 ROW4 4 24 34 44 54 64 74 84 94 104 ROW5 5 25 35 45 55 65 75 85 95 105 ROW6 6 26 36 46 56 66 76 86 96 106 ROW7 7 27 37 47 57 67 77 87 97 107 ROW8 8 28 38 48 58 68 78 88 98 108 ROW9 9 29 39 49 59 69 79 89 99 109 ROW10 10 30 40 50 60 70 80 90 100 110 col1 col2 col3 col4 col5 col6 col7 col8 col9 col10 ROW2 2 22 32 42 52 62 72 82 92 102 ROW3 3 23 33 43 53 63 73 83 93 103 ROW4 4 24 34 44 54 64 74 84 94 104 ROW6 6 26 36 46 56 66 76 86 96 106 ROW7 7 27 37 47 57 67 77 87 97 107 ROW8 8 28 38 48 58 68 78 88 98 108 ROW9 9 29 39 49 59 69 79 89 99 109 ROW10 10 30 40 50 60 70 80 90 100 110 データフレームで使用できる分析関数 †TODO:
ファイル操作 †writeによるファイル出力 †以下、行列をファイルに出力する例を記載する。 > x <- matrix(1:10, ncol=2) > x [,1] [,2] [1,] 1 6 [2,] 2 7 [3,] 3 8 [4,] 4 9 [5,] 5 10 > write(x, file="data_matrix.txt", ncolumns=2) 結果は転置されて出力される。 (結果) 1 2 3 4 5 6 7 8 9 10 転置せずに出力する場合は、事前に t で転置してから出力する。 > write(t(x), file="data_matrix.txt", ncolumns=2) (結果) 1 6 2 7 3 8 4 9 5 10 scan によるファイル読み込み †scan でファイルのデータをベクトルとして読み込む事ができる。 > x <- matrix(1:10, ncol=5, byrow=T) > x [,1] [,2] [,3] [,4] [,5] [1,] 1 2 3 4 5 [2,] 6 7 8 9 10 > write(x, "test_matrix.txt") > y <- scan("test_matrix.txt") Read 10 items > y [1] 1 6 2 7 3 8 4 9 5 10 結果はベクトルになるので行列に変換する場合は matrix で自分で変換する。 > matrix(y, ncol=5) [,1] [,2] [,3] [,4] [,5] [1,] 1 2 3 4 5 [2,] 6 7 8 9 10 データ型が混在する場合はデータ型を明示しないとエラーになる。( what に列毎のデータ型 または 変換関数のリストを指定する ) x = data.frame(Name=c("Yamada", "Tanaka"), Age=c(20, 22), Sex=c("M","W")) write.table(x, "output.csv", quote=F, col.names=T, row.names=F, sep=",") system("cat output.csv") > system("cat output.csv") Name,Age,Sex Yamada,20,M Tanaka,22,W > scan("output.csv", skip=1, sep=",") scan("output.csv", skip = 1, sep = ",") でエラー: scan() 関数は 'a real' を期待したのに、得られたのは 'Yamada' でした > scan("output.csv", what=list("",numeric(),""), skip=1, sep=",") Read 2 records [[1]] [1] "Yamada" "Tanaka" [[2]] [1] 20 22 [[3]] [1] "M" "W" writeLines によるテキストファイル出力 †writeLines でテキストデータをファイルに出力する事ができる。 > con = file("sample.txt", open="w") > writeLines("This is Sample!", con) > writeLines("Hello R!!", con) > writeLines("This is 3rd Line.", con) > close(con) > > system("cat sample.txt") This is Sample! Hello R!! This is 3rd Line. cat に file オプションと sep オプションを指定しても同じ事ができる。 > con = file("sample.txt", open="w") > cat("This is Sample!", "Hello R!!", "This is 3rd Line.", file=con, sep = "\n") > close(con) > > system("cat sample.txt") This is Sample! Hello R!! This is 3rd Line. readLines によるテキストファイルの読み込み †readLines ではファイルから1行=1要素としたベクトルを得る事ができる。 sample.txt This is first Line. Hello R! 読み込み例 > x = readLines('sample.txt') > x [1] "This is first Line." "Hello R!" > x[1] [1] "This is first Line." > x[2] [1] "Hello R!" csvファイルの入出力 †read.table で csvファイルからデータフレームを生成できる。 browser-JP.csv ( http://gs.statcounter.com/browser-market-share/all/japan より ) "Date","Chrome","Safari","IE","Firefox","Edge","Android" 2018-06,41.96,31.83,11.5,6.63,4.29,0.97 2018-07,41.9,32.29,11.13,6.43,4.26,0.9 2018-08,42.54,31.91,11.15,6.44,4.23,0.9 2018-09,41.18,34.45,10.43,6.14,4.36,0.78 2018-10,43.11,33.01,10.2,6.2,4.23,0.69 2018-11,44.28,32.54,9.49,6.31,4.14,0.69 2018-12,44.47,31.96,9.21,6.81,4,0.74 読み込み例 > read.table("browser-JP.csv", sep=",", header=T, row.names="Date") Chrome Safari IE Firefox Edge Android 2018-06 41.96 31.83 11.50 6.63 4.29 0.97 2018-07 41.90 32.29 11.13 6.43 4.26 0.90 2018-08 42.54 31.91 11.15 6.44 4.23 0.90 2018-09 41.18 34.45 10.43 6.14 4.36 0.78 2018-10 43.11 33.01 10.20 6.20 4.23 0.69 2018-11 44.28 32.54 9.49 6.31 4.14 0.69 2018-12 44.47 31.96 9.21 6.81 4.00 0.74 ※sep="," で 列の区切り文字を指定している。 write.table でデータフレームをCSVファイルに出力できる。 > write.table(x, "output.csv", quote=F, col.names=T, row.names=T, sep=",") ※詳細は ?write.table で確認。 Excelへのデータ出力 †インストール install.packages("xlsx") install.packages('rJava') 手元のMacではインストール時に以下のエラーを吐いてコケる。 警告メッセージ: doTryCatch(return(expr), name, parentenv, handler) で: 共有ライブラリ '/Library/Frameworks/R.framework/Resources/modules//R_X11.so' を読み込めません: dlopen(/Library/Frameworks/R.framework/Resources/modules//R_X11.so, 6): Library not loaded: /opt/X11/lib/libcairo.2.dylib Referenced from: /Library/Frameworks/R.framework/Resources/modules//R_X11.so Reason: Incompatible library version: R_X11.so requires version 11403.0.0 or later, but libcairo.2.dylib provides version 11203.0.0 R_X11.so のバージョンが古いらしいので https://github.com/satijalab/seurat/issues/299 を参考に、以下の通り対応。 brew cask install xquartz 実際に使おうとすると、今度は以下のエラーになる。 > library(xlsx) エラー: package or namespace load failed for ‘xlsx’: .onLoad は loadNamespace()('rJava' に対する)の中で失敗しました、詳細は: call: dyn.load(file, DLLpath = DLLpath, ...) error: 共有ライブラリ '/Library/Frameworks/R.framework/Versions/3.5/Resources/library/rJava/libs/rJava.so' を読み込めません: dlopen(/Library/Frameworks/R.framework/Versions/3.5/Resources/library/rJava/libs/rJava.so, 6): Library not loaded: /Library/Java/JavaVirtualMachines/jdk-11.0.1.jdk/Contents/Home/lib/server/libjvm.dylib Referenced from: /Library/Frameworks/R.framework/Versions/3.5/Resources/library/rJava/libs/rJava.so Reason: image not found どうもインストールされていないJDKのバージョンのものを探してる模様。 library(xlsx) x = read.table("browser-JP.csv", sep=",", header=T, row.names="Date") write.xlsx(x, "output.xlsx", sheetName="Sheet1", col.names=TRUE, row.names=TRUE, append=FALSE, showNA=TRUE, password=NULL) ※ https://www.rdocumentation.org/packages/xlsx/versions/0.6.1/topics/write.xlsx オブジェクトの保存と読み込み †R ではオブジェクトそのものをファイルに保存したり、ファイルから復元する事ができる。 ベクトル x をファイルに保存) > x <- 1:10 > x [1] 1 2 3 4 5 6 7 8 9 10 > save(x, file="x.rdata") いちど変数を削除後にファイルから x を読み込む) > rm(x) > x エラー: オブジェクト 'x' がありません > load("x.rdata") > x [1] 1 2 3 4 5 6 7 8 9 10 ファイル一覧の取得 †list.files("/tmp", full.names = F) ※結果はlist applyファミリー †他の言語の map や apply 等と同様に R にも行列やデータフレームの各要素に対して関数を適用する仕組みがある。 apply †apply は行列やデータフレームの各要素に関数を適用する。 形式)
引数)
利用例1) > x = data.frame(col1=c(1,2,3,4,5), col2=c(6,7,8,9,10), col3=c(11,12,13,14,15)) > x col1 col2 col3 1 1 6 11 2 2 7 12 3 3 8 13 4 4 9 14 5 5 10 15 > apply(x, 1, sum) # 行毎の合計 [1] 18 21 24 27 30 > apply(x, 2, sum) # 列毎の合計 col1 col2 col3 15 40 65 利用例2) > myfunc <- function(x){ + return (x*2) + } > apply(x, 1:2, myfunc) col1 col2 col3 [1,] 2 12 22 [2,] 4 14 24 [3,] 6 16 26 [4,] 8 18 28 [5,] 10 20 30 lapply †リストに関数を適用しリストを返却する。 TODO:
sapply †リストに関数を適用しベクトル または 行列を返す。 TODO:
tapply †グループ化されたデータについてグループ毎に関数を適用する。 形式)
引数)
利用例) > name <- c("Yamada", "Tanaka", "Sato", "Suzuki", "Yamamoto", "Takahashi", "Kobayashi", "Kato", "Ito", "Watanabe") > sex <- c("W", "M", "M", "M", "W", "W", "W", "W", "M", "W") > state <- c("Osaka", "Tokyo", "Osaka", "Osaka", "Nagoya", "Osaka", "Tokyo", "Tokyo", "Nagoya", "Tokyo") > height <- c(170.5, 175.4, 171.2, 173.6, 169.8, 165.2, 178.1, 165.5, 173.2, 172.9) > > x <- data.frame(Name=name, Sex=sex, State=state, Height=height) > > # 都道府県ごとの平均身長 > tapply(x$Height, list(x$State), mean) Nagoya Osaka Tokyo 171.500 170.125 172.975 > > # 男女毎の平均身長 > tapply(x$Height, list(x$Sex), mean) # INDEXには tapply(x$Height, factor(x$Sex), mean) で factor を指定してもOK M W 173.3500 170.3333 > > # 都道府県、男女毎の平均身長 > tapply(x$Height, list(x$State, x$Sex), mean) M W Nagoya 173.2 169.8000 Osaka 172.4 167.8500 Tokyo 175.4 172.1667 mapply †TODO:
乱数の生成 †乱数の生成を行う為の関数が豊富に用意されている。 正規分布 †例)身長データを100個生成する。(平均値は 170、標準偏差は 10とする) > x = rnorm(100, mean = 170, sd = 10) # 乱数の生成 > round(x, digits = 1) # 小数点以下1桁になるように四捨五入 [1] 164.3 180.4 182.8 190.1 154.7 177.2 168.7 167.2 160.9 177.9 168.2 173.4 168.7 177.5 166.9 163.7 174.2 153.8 [19] 187.5 164.4 154.6 172.6 175.1 181.1 184.3 148.7 172.7 160.8 149.0 163.7 184.1 162.7 161.8 183.5 171.8 177.9 [37] 164.6 170.1 165.5 182.7 178.2 171.7 156.0 177.9 174.0 186.0 153.5 176.4 183.5 166.2 179.9 174.1 146.0 159.1 [55] 169.1 163.7 172.6 165.2 171.3 184.8 177.0 181.6 164.6 154.1 178.9 175.7 170.1 155.8 161.9 153.9 186.8 184.9 [73] 170.0 176.7 166.7 166.5 177.8 179.4 169.6 179.1 177.6 169.7 175.8 151.1 178.9 183.6 158.3 172.0 149.6 162.6 [91] 158.6 153.6 180.5 177.6 168.4 163.0 171.2 159.9 156.3 173.2 XXXXXXXXXX †TODO:
因子型(factor) †分析関数 † |