ブログの説明

学校に通わないで学んだことを記しています。間違っているところが何かありましたらご指摘下さると幸いです。コメントに対する返信が遅れる可能性があります。その場合は申し訳ありません。

このブログではサイドバーに広告を表示しています。このブログ内の投稿記事を検索するには右上の拡大鏡のアイコンを、アーカイブやラベル付けから投稿記事を閲覧するには左上の三重線のアイコンをクリックして下さい。

数式の表示にはMathJaxを利用させていただいています。数式の表示のためにJavaScriptが有効である必要があります。そうでない場合、訳の分からないLatexのコードが表示されます。幾何学図形やチャートの表示にはHTML5 CanvasやGoogle Chartを使用しています。その表示のためにもJavaScriptが有効である必要があります。

できる男は表計算ソフトでなくR言語を使う その1

Debian GNU/Linux 8でのR言語のインストールと起動・終了

とりあえず、r-baseというdebパッケージをインストールする。すると依存関係によっていくつかの基本的なパッケージがインストールされる。Ubuntuでもおそらく同じパッケージ名のはず。OpenSUSEではR-baseというパッケージ名であるようだ。FedoraやVineでは大文字のRというパッケージ名で、ArchlinuxやManjaroでは小文字のrというパッケージ名のようだ。

ちなみに、WindowsユーザーとMacユーザーはhttps://cran.r-project.org/mirrors.htmlからダウンロードすることができるようだ。お近くのミラーサーバを選び、Windowsユーザーは「Download R for Windows」というリンクをクリックしてbaseをダウンロードしてインストールし、Macユーザーは「Download R for (Mac) OS X」をクリックして適切なバージョンのpkgをダウンロードしてインストールすれば使えるようだ。

Debian GNU/Linux 8でのインストール。

$ sudo apt-get update
$ sudo apt-get install r-base

適切に環境設定が行われていれば、コマンドライン上で大文字のRと入力してEnterキーを押せばRが起動する。

$ R

バージョン番号やちょっとした説明とともに次のようなプロンプトが表示される。ここで使用するR言語のバージョンは3.1.1。

>

Rを終了するにはq()と入力してEnterキーを押す。すると次のようなメッセージが出る。

> q()
Save workspace image? [y/n/c]:

ワークスペース・イメージを保存するか問われる。yなら保存して終了。nなら保存しないで終了。cなら終了しない。ワークスペース・イメージを保存すると、そのときに定義して値を代入した変数が次の起動時にもそのまま有効になっていて使える。

R言語の使い方あれこれ

R言語では変数へ値を入れるための代入演算子が一般的なものとは少しちがっている。

> a1 <- 5
> 15 -> a2
> a1 + a2
[1] 20

<-または<<-を使えば右の値を左の変数へ代入することができ、->または->>を使えば左の値を右の変数へ代入することができる。もちろん、<-の代わりに=を使うこともできる。

R言語は大文字と小文字を区別する。代入演算子の=は<-と同じ意味。

> A1 = 20
> a1 - A1
[1] -15

変数名にはもちろん予約語は使えず、数字で始めることができないので要注意。

> 1b <- 3
 エラー:  予想外の  シンボル  です  in "1b"

配列を変数に代入するには、次のようにする。R言語では配列をベクトルと呼ぶ。数学の行列でいうところの数ベクトル、つまり行ベクトルや列ベクトルのことだろうか。ベクトルを作るためにはc()関数を使う。cは英単語combineの頭文字らしく、データ同士を結合するのに使うもののようだ。

> a <- c(0, 2, 4, 6, 8, 10)
> b <- c(10, 8, 6, 4, 2, 0)

assign()という関数を使って代入を行うこともできる。第一引数に""を使って変数名を指定し、カンマで区切って第二引数にベクトルを指定する。

> assign("c",c(0, 1, 2, 3, 4, 5))

0, 1, 2, 3, 4, 5のような数列は次のように記述することができる。

> c(0:5)
[1] 0 1 2 3 4 5

seq()関数を使えば等差数列のようなものを生成することができる。第一引数に開始値、第二引数に終了値、第三引数に交差。それぞれfrom=, to=, by=というふうに明示することもできる。この場合は引数の順序は無関係。引数が一つだけの場合は下のようになる。

> seq(10)
 [1]  1  2  3  4  5  6  7  8  9 10
> seq(0, 5)
[1] 0 1 2 3 4 5
> seq(10, 0)
 [1] 10  9  8  7  6  5  4  3  2  1  0
> seq(0, 10, 2)
[1]  0  2  4  6  8 10
> seq(10, 0, -2)
[1] 10  8  6  4  2  0
> seq(from=0, to=10, by=2)
[1]  0  2  4  6  8 10
> seq(by=3, to=10, from=0)
[1] 0 3 6 9
> a1 <- c( seq(0, 10, 2) )
> a1
[1]  0  2  4  6  8 10
> a2 <- c( seq(from=10, to=0, by=-2) )
> a2
[1] 10  8  6  4  2  0
> seq(0, 10, -2)
 以下にエラー seq.default(0, 10, -2) :  'by' 引数中に誤った符号があります
> seq(10, 0, 2)
 以下にエラー seq.default(10, 0, 2) :  'by' 引数中に誤った符号があります

誤った引数を指定するとエラーになってしまう。

manコマンドのようなものがR言語にもある。それが?コマンド。一種のヘルプだ。次のようにするとその説明文を表示してくれる。しかし英文だった。そこから抜け出すにはqを押す。

> ?seq
または
> ?"seq"

これはhelp()関数を使った場合と同じことを意味している。

> help(seq)

helpから抜け出すにはqキーを押す。

特殊記号や予約語を""で挟まずにそのまま引数にすると、次のようなエラーになってしまうようだ。

> help(->)
 エラー:  予想外の '->' です  in "help(->"
> ?*
 エラー:  予想外の '*' です  in "?*"
> help("*")
> ?"->"
> help(if)
 エラー:  予想外の ')' です  in "help(if)"

helpは英文なので分かりにくい。その代わり実行例を示してくれるexample()関数を使うほうが直観的に分かりやすく便利かもしれない。

> example(assign)

ベクトル同士を+演算子を使って足し合わせると、ベクトルの各成分同士が足し合わされ、行列の加法と同じ結果を得られる。ベクトル同士を-演算子を使って引いた場合も行列の減法と同じ結果を得られる。もちろん計算結果をそのまま変数に代入して使ってもよい。

> a <- c(0, 2, 4, 6, 8, 10)
> b <- c(10, 8, 6, 4, 2, 0)
> a
[1]  0  2  4  6  8 10
> b
[1] 10  8  6  4  2  0
> a + b
[1] 10 10 10 10 10 10
> a - b
[1] -10  -6  -2   2   6  10
> x <- a + b
> x * c
[1]  0 10 20 30 40 50

R言語では次のような算術演算子を使うことができる。

主な算術演算子
演算子 意味
+ 加法(足し算)
- 減法(引き算)
* 乗法(かけ算)
/ 除法(割り算)
^ 累乗(べき乗)
%% 剰余(割り算の余り)
%/% 除法の結果の小数点以下切り捨て
> 5 ^ 3
[1] 125
> 10 / 1.5
[1] 6.666667
> 10 %/% 1.5
[1] 6
> 5^2 * pi # 半径5の円の面積
[1] 78.53982
> sqrt(4)
[1] 2
> sqrt(2)
[1] 1.414214
> sqrt(4)
[1] 2
> sqrt(2) * sqrt(4)
[1] 2.828427

#以降は改行までコメント。円周率はpiと入力すれば認識してくれる。sqrt()はルートを意味する。

ベクトルの中の各成分を参照するには、多くのプログラミング言語で配列の要素を参照するのと同様に次のようにする。

> b[5]
[1] 8
> c[3]
[1] 6

ベクトル変数bの左から数えて4つめの値と、ベクトル変数cの左から3つめの値が出力される。

加算ではなく、ベクトルに成分を加えたり、ベクトル同士を結合するのは、新たなベクトルを作ってその成分にベクトルを組み込むことで実現することができる。

> c(a, 12)
[1]  0  2  4  6  8 10 12
> c(a, 12, 14, 16)
[1]  0  2  4  6  8 10 12 14 16
> c(a, b)
 [1]  0  2  4  6  8 10 10  8  6  4  2  0

小数の成分をベクトル変数に加えると、他の成分もすべて小数になってしまう。また、""を使った成分を加えるとそれは文字列として認識され、他の成分までが文字列になってしまう。

> c(b, 0.8, 0.6)
[1] 10.0  8.0  6.0  4.0  2.0  0.0  0.8  0.6
> c(a, "12")
[1] "0"  "2"  "4"  "6"  "8"  "10" "12"

文字列との算術演算はできないので要注意。

> c = c(a, "12")
> a + b + c
 以下にエラー a + b + c :  二項演算子の引数が数値ではありません

ベクトル内のある成分を別の値に置き換えるには先程の参照の方法を用いる。

> a
[1]  0  2  4  6  8 10
> a[5] <- 80
> a
[1]  0  2  4  6 80 10
> a[5] <- 8
> a
[1]  0  2  4  6  8 10

ベクトルの成分を選んで削除するには次のようにする。seq()は数列を作ってくれる関数。

> aa <- c( seq(0, 16, 2))
> aa
[1]  0  2  4  6  8 10 12 14 16
> aa <- aa[-9]
> aa
[1]  0  2  4  6  8 10 12 14
> aa <- aa[c(-7,-8)]
> aa
[1]  0  2  4  6  8 10

aa[-9]はaaというベクトル変数の左から9番目の成分を削除するという意味であり、その結果をaaに代入している。aa[c(-7,-8)]はaaというベクトル変数の左から7番目と8番目の成分を共に削除するという意味であり、その結果をaaに代入している。

R言語で扱うデータはいずれかのモードに分類されている。モードの種類は次のとおり。

モード
モード名 意味
numeric 数値
character 文字
vector ベクトル
matrix 行列
array 配列
list リスト
data.frame データフレーム
logical 論理
complex 複素数
factor 順序なし因子
ordered 順序あり因子

mode()関数やclass()関数を使うとモードを調べてくれる。モードとクラスは厳密には違うのかもしれないが、mode()もclass()も同じ結果を出してくれる。

> mode(F)
[1] "logical"
> mode(c(1:10))
[1] "numeric"
> ch <- "Hello, World!"
> mode(ch)
[1] "character"
> mode(c)
[1] "function"
> class(seq)
[1] "function"
> class(pi)
[1] "numeric"

piは円周率。

numeric(数値)モードは更に2つのタイプに分けられている。

タイプ
タイプ名 意味
integer 整数
double 実数

typeof()関数を使うとモードと、numericの場合はそのタイプ(integerかdoubleか)まで調べてくれる。

> dec <- 5
> typeof(dec)
[1] "double"
> int <- as.integer(5)
> typeof(int)
[1] "integer"
> typeof(pi)
[1] "double"

is.モード名()またはis.タイプ名()という名前を持つ関数によってその変数が持つ値のモードやタイプを確認することができる。TRUEは真、FALSEは偽という意味。

> t1 <- c(1:10)
> t2 <- c("a","b","c")
> is.numeric(t1)
[1] TRUE
> is.numeric(t2)
[1] FALSE
> is.character(t1)
[1] FALSE
> is.character(t2)
[1] TRUE
> is.integer(5)
[1] FALSE
> is.integer(c(1:5))
[1] TRUE
> is.double(5)
[1] TRUE
> is.double(c(1:5))
[1] FALSE

5がinteger(整数)と判定されないのはなぜだろうか?

as.モード名()またはas.タイプ名()という名前を持つ関数を使うと、可能ならば、そのモードやタイプへとデータを変換することができる。

> is.character(t1)
[1] FALSE
> as.character(t1)
 [1] "1"  "2"  "3"  "4"  "5"  "6"  "7"  "8"  "9"  "10"
> is.numeric(t2)
[1] FALSE
> as.numeric(t1)
 [1]  1  2  3  4  5  6  7  8  9 10
> is.numeric(t1)
[1] TRUE
> as.numeric(t2)
[1] NA NA NA
 警告メッセージ:
 強制変換により NA が生成されました
> t2
[1] "a" "b" "c"
> is.numeric(t2)
[1] FALSE
> n <- as.integer(5)
> is.integer(n)
[1] TRUE

文字の値が数ならば数値型へ変えることができるが、t2というベクトルには"a","b","c"というアルファベットが入っているので、数値への変換はできなかったようだ。

list()関数を使えば、異なる種類のデータでもひとつにまとめることができる。これはリストと呼ばれている。c()はデータをベクトルへとまとめてくれる関数。seq()は数列を作ってくれる関数。mode()はデータの種類を調べて表示してくれる関数。

> numeric <- c( seq(10, 50, 10) )
> character <- c("Hello", "Goodbye")
> logical <- c(T, F)
> mode(numeric)
[1] "numeric"
> mode(character)
[1] "character"
> mode(logical)
[1] "logical"
> mylist <- list(numeric, character, logical)
> mode(mylist)
[1] "list"
> mylist
[[1]]
[1] 10 20 30 40 50

[[2]]
[1] "Hello"   "Goodbye"

[[3]]
[1]  TRUE FALSE

リストの成分はベクトルのように参照することができる。

> mylist
[[1]]
[1] 10 20 30 40 50

[[2]]
[1] "Hello"   "Goodbye"

[[3]]
[1]  TRUE FALSE

> mylist[[1]]
[1] 10 20 30 40 50
> mylist[[2]][2]
[1] "Goodbye"
> mylist[[3]][1]
[1] TRUE

[[]]の次に[]を使うことでその中の成分を特定して参照することができる。

リストに成分を追加しようとして次のようにしたら、予期せぬ結果が得られた。

> mylist <- list(mylist, c("a", "b", "c"))
> mylist
[[1]]
[[1]][[1]]
[1] 10 20 30 40 50

[[1]][[2]]
[1] "Hello"   "Goodbye"

[[1]][[3]]
[1]  TRUE FALSE


[[2]]
[1] "a" "b" "c"

この方法だとリストが入れ子構造になってしまう。しかし次のようにすればうまくいった。

> mylist[4] <- list( c("a", "b", "c") )
> mylist
[[1]]
[1] 10 20 30 40 50

[[2]]
[1] "Hello"   "Goodbye"

[[3]]
[1]  TRUE FALSE

[[4]]
[1] "a" "b" "c"

リストの成分を削除するには、ベクトルの成分を削除したのと同じように次のようにする。

> mylist
[[1]]
[1] 10 20 30 40 50

[[2]]
[1] "Hello"   "Goodbye"

[[3]]
[1]  TRUE FALSE

[[4]]
[1] "a" "b" "c"

> mylist <- mylist[-4]
[[1]]
[1] 10 20 30 40 50

[[2]]
[1] "Hello"   "Goodbye"

[[3]]
[1]  TRUE FALSE

リストの成分を置き換えるには次のようにする。

> mylist
[[1]]
[1] 10 20 30 40 50

[[2]]
[1] "Hello"   "Goodbye"

[[3]]
[1]  TRUE FALSE

> mylist[1] <- list( c(5:15) )
> mylist
[[1]]
 [1]  5  6  7  8  9 10 11 12 13 14 15

[[2]]
[1] "Hello"   "Goodbye"

[[3]]
[1]  TRUE FALSE

リストの成分の中の成分を置き換えるには、次のように[[]][]を使う。

> mylist
[[1]]
[1] 10 20 30 40 50

[[2]]
[1] "Hello"   "Goodbye"

[[3]]
[1]  TRUE FALSE

> mylist[[2]][2] <- "Sayonara"
> mylist
[[1]]
[1] 10 20 30 40 50

[[2]]
[1] "Hello"    "Sayonara"

[[3]]
[1]  TRUE FALSE

リストの成分には次のようにインデックスを付けることもできる。

> profile <- list(
+ name="Debian Linux",
+ age=25,
+ sex="female",
+ blood="A",
+ country="Finland")
> profile
$name
[1] "Debian Linux"

$age
[1] 25

$sex
[1] "female"

$blood
[1] "A"

$country
[1] "Finland"

参照するにはインデックスを使う。

> profile$age
[1] 25
> profile$country
[1] "Finland"

matrix()関数を使うと、行ベクトルと列ベクトルを持った2次元のベクトル、つまり行列(マトリックス)を作ることができる。

> a <- c(1:9) # ベクトルを作成
> mtx1 <- matrix(
+ a, # ベクトル変数
+ nrow=3, # 列の数
+ ncol=3, # 行の数
+ byrow=TRUE)
> mtx1
     [,1] [,2] [,3]
[1,]    1    2    3
[2,]    4    5    6
[3,]    7    8    9
> mtx2 <- matrix(
+ a,
+ nrow=3,
+ ncol=3,
+ byrow=FALSE)
> mtx2
     [,1] [,2] [,3]
[1,]    1    4    7
[2,]    2    5    8
[3,]    3    6    9

見やすいようにmatrix()関数の引数に改行を入れてみた。matrix()関数の最初の引数にはベクトルを代入しておいた変数aを指定し、nrowで列の数、ncolで行の数を指定した。つまり3列3行の行列になる。m1ではbyrowをTRUEにしてあるのでベクトルの成分が行並びに配置され、m2ではbyrowをFALSEにしてあるのでベクトルの成分が列並びに配置されているのが見て取れる。

行列の演算をしてみた。まずは加法。+演算子を使う。

> mtx1; mtx2
     [,1] [,2] [,3]
[1,]    1    2    3
[2,]    4    5    6
[3,]    7    8    9
     [,1] [,2] [,3]
[1,]    1    4    7
[2,]    2    5    8
[3,]    3    6    9
> mtx1 + mtx2
     [,1] [,2] [,3]
[1,]    2    6   10
[2,]    6   10   14
[3,]   10   14   18

行列の成分ごとに足し合わされているのが分かる。

次には行列の減法。引き算。-演算子を使う。

> mtx1; mtx2
     [,1] [,2] [,3]
[1,]    1    2    3
[2,]    4    5    6
[3,]    7    8    9
     [,1] [,2] [,3]
[1,]    1    4    7
[2,]    2    5    8
[3,]    3    6    9
> mtx1 - mtx2
     [,1] [,2] [,3]
[1,]    0   -2   -4
[2,]    2    0   -2
[3,]    4    2    0

行列の成分ごとに引き算されているのが分かる。

次は行列の乗法と除法。かけ算と割り算。*演算子と/演算子を使う。

> mtx1; mtx2
     [,1] [,2] [,3]
[1,]    1    2    3
[2,]    4    5    6
[3,]    7    8    9
     [,1] [,2] [,3]
[1,]    1    4    7
[2,]    2    5    8
[3,]    3    6    9
> mtx1 * mtx2
     [,1] [,2] [,3]
[1,]    1    8   21
[2,]    8   25   48
[3,]   21   48   81
> mtx1 / mtx2
         [,1]     [,2]      [,3]
[1,] 1.000000 0.500000 0.4285714
[2,] 2.000000 1.000000 0.7500000
[3,] 2.333333 1.333333 1.0000000

数値行列のみならず文字の行列も作ることができる。

> chr <- c("apple","orange","banana","pear","chestnut")
> cn <- length(chr)
> mtx3 <- matrix(
+ chr,
+ nrow=cn,
+ ncol=cn,
+ byrow=TRUE)
> mtx3
     [,1]    [,2]     [,3]     [,4]   [,5]
[1,] "apple" "orange" "banana" "pear" "chestnut"
[2,] "apple" "orange" "banana" "pear" "chestnut"
[3,] "apple" "orange" "banana" "pear" "chestnut"
[4,] "apple" "orange" "banana" "pear" "chestnut"
[5,] "apple" "orange" "banana" "pear" "chestnut"

length()はベクトルの成分の数を取得してくれる関数。

3次元以上のデータはarray()関数を使って作ることができる。それをR言語では配列と呼んでいるらしい。2次元のベクトル(行列)もarray()を使って作ることができる。

> mtx4 <- array(1:15,dim=c(5,3))
> mtx4
     [,1] [,2] [,3]
[1,]    1    6   11
[2,]    2    7   12
[3,]    3    8   13
[4,]    4    9   14
[5,]    5   10   15

1:15は1から15までの数値を指定している。dim=c(5,3)で列5行3の次元を指定している。

今回はここまで。

終了するにはq()と入力してEnterキーを押す。ワークスペース・イメージを保存するためにyを選択して終了する。

> q()
Save workspace image? [y/n/c]: y
R言語の公式ホームページ
https://www.r-project.org/

コメント

このブログの人気の投稿

LATEXで数式:指数と順列などで使う添数・添字

10の補数と9の補数と2の補数と1の補数

Visual Studio 2019にはC++のためのフォームデザイナーがない件