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, . .
変数への代入は <- または -> で行う。
以下は、1〜5までの連続した値のベクトルを生成し、x という変数に代入している。
> 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 というファイルに保存されている。
※これらのファイルを消せばワークスペースの状態を初期化できる。
test.R
x <- 1:10 cat(x)
実行
rscript test.R 1 2 3 4 5 6 7 8 9 10
以下のビルトイン定数やオブジェクトが使用できる。
定数名 | 説明 |
NULL | NULLオブジェクト。※null値の判定は is.null(変数) で可能。 |
NaN | 未定義を示す値 |
TRUE, T | 真偽値のTrue |
FALSE, F | 真偽値のFalse |
LETTERS | A〜Zのベクトル |
letters | a〜zのベクトル |
month.abb | 1月〜12月の略称のベクトル |
month.name | 1月〜12月のベクトル |
pi | π |
> 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
> x <- 1:10 > print(x) [1] 1 2 3 4 5 6 7 8 9 10
書式付きでオブジェクトを表示する場合には sprint を使用する。
> sprintf("%3.2f", 123.456) [1] "123.46"
cat を使用すれば文字列をダブルクォーテーションなしで表示できる。
> str1 = "ABCDEFG" > cat(str1) ABCDEFG
str を使用すると、オブジェクトの内容をデータ型などの情報付きで表示できる。
> str1 = "123" > str(str1) chr "123"
length、ncol、nrow でベクトルや行列等の長さを調べる事ができる。
また、文字列の長さを調べる場合は length でなく nchar を使用する。
> 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 で列毎の概要を表示する事ができる。
> 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文が使用できる。
ただし R の for文は遅いので処理を関数化して apply系で記述する方が高速に動作する。
> for (i in 1:5) { + print(i) + } [1] 1 [1] 2 [1] 3 [1] 4 [1] 5
while ループを使用する事もできる。
※例では示さないが break も使用可能。
> 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
関数名 <- function(引数,...) で関数を定義する事ができる。
> myfunc <- function(x) { + return (x*2) + } > > myfunc(2) [1] 4 > myfunc(10) [1] 100
シェル等で使用する | と同等の機能は「%>%」 で実現できる。
dplyr::group_by や summarise をパイプと共に利用するとかなり便利。
> # 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 Count1 Nagoya 2 2 Osaka 4 3 Tokyo 4
> paste("abc", "def", sep="") [1] "abcdef"
strsplit で文字列を分割する事ができる。
※ただし結果はリストオブジェクトなので、unlist 等でベクトルに変換する等の処置が必要。
> 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
上記を分けて書くと以下のようになる。
※真偽値リストを条件に指定して真である要素を書き換えている。(pandasのデータフレーム等と同じやり方)
> 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() でベクトルを結合した別のベクトルを得る事ができる。
※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 を使用するとベクトルに要素を追加した別のベクトルを得る事ができる。
※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 で行列を結合する事ができる。
※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 = 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
以下、行列をファイルに出力する例を記載する。
> 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 でファイルのデータをベクトルとして読み込む事ができる。
> 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 でテキストデータをファイルに出力する事ができる。
> 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 ではファイルから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!"
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="," で 列の区切り文字を指定している。
※header=T で1行目は列名である事を示している。
※row.names で行ラベルに使用する列名を指定している。(上記では "Date" 列のデータを行ラベルとして扱う旨を示している)
※詳細は ?read.table で確認。
write.table でデータフレームをCSVファイルに出力できる。
> write.table(x, "output.csv", quote=F, col.names=T, row.names=T, sep=",")
※詳細は ?write.table で確認。
インストール
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のバージョンのものを探してる模様。
解決方法を調べてみると dyn.load("/path/to/libjvm.dylib") で libjvm.dylib の場所を指定する方法や /usr/local/lib/ にシンボリックリンクを貼る方法等が見つかったが、
ここでは素直に jdk11 をインストールした。( Java11から商用利用は有償になるので corretto とかの方が良いかも )
https://www.oracle.com/technetwork/java/javase/downloads/jdk11-downloads-5066655.html
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
他の言語の map や apply 等と同様に R にも行列やデータフレームの各要素に対して関数を適用する仕組みがある。
※Rのループは遅いので繰り返し処理の内容を関数化しておいて apply する等の用途でも利用される。
apply は行列やデータフレームの各要素に関数を適用する。
形式)
apply(X, MARGIN, FUN, ...) |
引数)
引数 | 説明 |
X | データフレーム または 行列を指定する |
MARGIN | 行に対して処理する場合は 1 、列に対して処理する場合は 2 、両方に対して処理する場合は c(1,2) を指定する |
FUN | 適用する関数を指定する |
利用例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
リストに関数を適用しリストを返却する。
リストに関数を適用しベクトル または 行列を返す。
グループ化されたデータについてグループ毎に関数を適用する。
形式)
tapply(X, INDEX, FUN = NULL, ..., default = NA, simplify = TRUE) |
引数)
引数 | 説明 |
X | データフレーム または 行列を指定する |
INDEX | グループ分けに使用するデータを リスト または factor で指定する ( 因子型(factor) ) |
FUN | 適用する関数を指定する |
利用例)
> 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
乱数の生成を行う為の関数が豊富に用意されている。
例)身長データを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