2 基礎

Rを使うときは,常に,「このコードを実行するとこうなるはずだ」と予想してください。 予想通りの結果が得られた場合,自分の予想は正しかったことが確かめられます。 予想とは異なる結果が得られた場合,次の2つの可能性が考えられます。

  1. 予想の元となった自分の考えが間違っていた。
  2. コードが間違っていた。

どちらが原因で予想と異なる結果が得られたかを考えてください。 前者の場合は自分の考えを改める必要があります。 Rの学習は,この予想と結果を合わせていく作業です。 常に,予想した結果が得られなければなりません。

2.1 データの型

データの型には,数値,文字列,ファクター(因子),論理値があります。 以下のどれかのコマンドを使って,そのデータの型を知ることができます。

typeof()
mode()
class()

ただし,常に意識するというよりは,エラーの原因追及(バグフィックス)時に必要な知識です。 このため,自分が書いたスクリプトにバグが入らないようにしたいなら,このデータの型を意識しておかなければなりません。 データの型には次の種類があります。

  1. 実数
  2. 整数
  3. 文字列
  4. ファクター
  5. 論理値

2.1.1 数値

実数と整数はいずれも数値で,区別しなくても困りません。 数値は計算できます。 任意のオブジェクトが数値かどうかを判定したいときは,is.double() または is.numeric() を用います。

x <- 10
is.double(x)
## [1] TRUE
is.numeric(x)
## [1] TRUE

返り値の TRUE は真という意味で,判定(知りたいこと)が真のときに TRUE が返ってきます。 判定が偽のときに FALSE が返ってきます。

Rではデフォルトで数値は実数として扱われます。 数字を扱うにあたって,それ以上のことを考える必要はありません。 もし整数として明示的に扱いたい場合は,次の関係を知っておいてください。

x <- 10
is.integer(x)
## [1] FALSE
x <- 10L
is.integer(x)
## [1] TRUE
x <- as.integer(10)
is.integer(x)
## [1] TRUE

また,整数は整数として意識的に維持しなければ,容易に実数に変化します。

10L + 2; is.integer(10L + 2)
## [1] 12
## [1] FALSE
10L + 2L; is.integer(10L + 2L)
## [1] 12
## [1] TRUE

多くの場合,数値を扱いたい場合であっても,整数ではなく,実数を使って問題はありません。

2.1.2 文字列

文字列は文字として表現されるもので,"" で括って表記します。

c("a", "あ", 'b')
## [1] "a"  "あ" "b"

多くの場合,""'' で代替できます。 ただし,Rの返り値は必ず "" で括られますので,'' ではなく "" を使う方が分かりやすいと思います。

c("a", "あ", "b")
## [1] "a"  "あ" "b"

それでは,扱いたい文字列の中に " を入れたい場合はどうすればよいでしょうか。 文字列の中に " を入れたい場合には '' を使うとよいです。

x <- '"あ"'
x
## [1] "\"あ\""

おや,返り値がおかしいですね。 いや,これでいいのです。 \ のことをエスケープシーケンスと呼びます。 \ を使うことで " の機能を避けて,文字列の中に " を入れることができます。

エスケープシーケンスを使うと,文字列は常に "" で括れます。

x <- "\"\""
x
## [1] "\"あ\""

文字列をくっつける関数に paste() があります。 次のように使います。

x <- "愛媛"
y <- "県"
paste(x, y)
## [1] "愛媛 県"

デフォルトでは結合部分に半角スペースが入ります。 結合部分に入れる文字は,引数 sep で指定します。 何も入れたくない場合は,次のようにします。

paste(x, y, sep = "")
## [1] "愛媛県"

数値を文字列に変換する場合は,as.character() を使います。 ただし,paste() の方が便利なため,paste() を頻繁に使うことになるでしょう。 例えば次のようにします。

paste(2000:2010, "年", sep = "")
##  [1] "2000年" "2001年" "2002年" "2003年" "2004年" "2005年" "2006年" "2007年"
##  [9] "2008年" "2009年" "2010年"

paste() は文字列を繋げる関数です。 引数には文字列を取りますので,引数に数値がある場合は,勝手に文字列に変換されます。

2.1.3 ファクター

ファクターは見た目は文字列ですが,以下の特徴があります。

  • 取り得る値の数が有限である。
  • グループ分けに使える。
  • 値に順序を付けることができる(順序はなくてもよい)。

例えば,学生の成績は「秀」「優」「良」「可」「不可」で表現されます。 あるいは,「S」「A」「B」「C」「D」といった表現もあります。 これらの文字列には順序があります。 「秀」は「優」より上,「優」は「良」より上です。

また,「愛媛県」は文字列で,一見順序は関係なさそうですが,日本の都道府県には都道府県コードが割り振られており,都道府県別に並べるとき,愛媛県は38番目に表示するというルールがあります。 「北海道」が01で,「沖縄県」が47です。 他に,アンケート調査票の中の問いの選択肢として,「強くそう思う」「ややそう思う」「どちらでもない」「あまりそう思わない」「まったくそう思わない」といったデータがあり得ます。

こうしたデータを扱う場合,ファクターを文字列として考えていると,思い通りの表示にならなかったり,処理できずエラーが返ってくることがあります。

次のデータがあったとします。

grade <- c("優", "良", "可", "良", "良", "不可", "秀", "優", "可", "良")
grade
##  [1] "優"   "良"   "可"   "良"   "良"   "不可" "秀"   "優"   "可"   "良"

このオブジェクト grade に順序を持たせるためには,次のようにします。

grade <- factor(grade, levels = c("不可", "可", "良", "優", "秀"))
grade
##  [1] 優   良   可   良   良   不可 秀   優   可   良  
## Levels: 不可 可 良 優 秀

ファクターの返り値に順序が Levels として表記されます。 この Levels はファクターに付けられたラベルであり,次のコマンドで取り出せます。

levels(grade)
## [1] "不可" "可"   "良"   "優"   "秀"

ファクターのラベルを変更すれば,ファクターの各要素の値も変わります。

levels(grade) <- c("D", "C", "B", "A", "S")
grade
##  [1] A B C B B D S A C B
## Levels: D C B A S

ファクターを文字列に変換すれば,ラベル(順序の情報)は失われます。

as.character(grade)
##  [1] "A" "B" "C" "B" "B" "D" "S" "A" "C" "B"

上述の説明は順序のようなものの存在を暗黙裏に扱っており,通常の使用ではこれで問題ありません。 もし明示的に水準の順序を扱いたい場合は,次のようにする必要があります。

factor(grade, levels = c("不可", "可", "良", "優", "秀"), ordered = TRUE)
##  [1] <NA> <NA> <NA> <NA> <NA> <NA> <NA> <NA> <NA> <NA>
## Levels: 不可 < 可 < 良 < 優 < 秀

また,上述のアンケート調査の例では,実際は,ファクターではなく,数値に変換して分析することもあります。

x <- factor(grade, levels = c("不可", "可", "良", "優", "秀"))
as.double(x)
##  [1] NA NA NA NA NA NA NA NA NA NA

2.1.4 論理値

オブジェクトの状態を表すものに,TRUEFALSE があります。 日本語では,TRUE は真で,FALSE で偽と表現します。 これまで関数の引数として登場しました。

TRUET と省略でき,FALSEF と省略できることを知っておいてください。 ただし,自分では TF を使わないでください。 複雑なコードのときに,TF よりも,TRUEFALSE の方が分かりやすいからです。 もしどこかでTF を見かけたら,頭の中でそれぞれ TRUEFALSE に置き換えてください。 なお,Truetrue ではなく,必ず大文字を使ってください。

論理値は,次のように扱います。

x <- rep(TRUE, 10)
x
##  [1] TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE

ここで,論理値が計算できることを知っておくと役に立つ場面があります。

x <- c(rep(TRUE, 6), rep(FALSE, 4))
sum(x)
## [1] 6

この例のように,TRUE のベクトルをわざわざ生成することは実際はほとんどありません。 実際には,比較演算子を用いた判定の返り値を計算に利用するときに,その返り値として登場します。 このとき,sum()TRUE の数に一致します。 つまり,sum(x)x の中の TRUE の数を数えていると理解してもよいです。 このことから推測できるように,R内部で TRUE は数値の 1 に変換され,FALSE は数値の 0 に変換された後,sum() が適用されています。 こうした性質を覚えておくと役立つことがあります。

2.2 データの構造

データの構造には以下の種類のものがあります。

  1. ベクトル
  2. 行列
  3. データフレーム
  4. リスト

2.2.1 ベクトル

ベクトルは,c() で作成します。

c(10, 12, 15, 20)
## [1] 10 12 15 20

seq() などの関数のように,返り値がベクトルとなるものもあります。

ベクトルの四則演算はベクトルを返します。

c(10, 12, 15, 20) * 5
## [1]  50  60  75 100

列ベクトルか行ベクトルかはあまり気にする必要はありません。

x <- 1990:2020
x
##  [1] 1990 1991 1992 1993 1994 1995 1996 1997 1998 1999 2000 2001 2002 2003 2004
## [16] 2005 2006 2007 2008 2009 2010 2011 2012 2013 2014 2015 2016 2017 2018 2019
## [31] 2020

ベクトルの転置は次のようにします。

t(x)
##      [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10] [,11] [,12] [,13] [,14]
## [1,] 1990 1991 1992 1993 1994 1995 1996 1997 1998  1999  2000  2001  2002  2003
##      [,15] [,16] [,17] [,18] [,19] [,20] [,21] [,22] [,23] [,24] [,25] [,26]
## [1,]  2004  2005  2006  2007  2008  2009  2010  2011  2012  2013  2014  2015
##      [,27] [,28] [,29] [,30] [,31]
## [1,]  2016  2017  2018  2019  2020

このことから,xx を転置した t(x) は中身が違うことが分かります。

ベクトルは数値である必要はなく,文字列のベクトルも作成できます。

c("テニス", "バレーボール", "野球", "サッカー")
## [1] "テニス"       "バレーボール" "野球"         "サッカー"

ただし,ベクトルの各要素の型は同じでなければなりません。 例えば,数値と文字列を混ぜた場合,そのベクトルは文字列になります。

x <- c(1, "テニス", 3)
x[1] + x[3]
## Error in `x[1] + x[3]`:
## ! 二項演算子の引数が数値ではありません

文字列は,たとえ見た目が数値であったとしても,計算できません。 文字列は必ず "" で括られています。

x
## [1] "1"      "テニス" "3"

ただし,文字列の中が数値の場合,その文字列は数値に変換できます。 文字列を数値に変換する場合は,as.double() を用います。

as.double(x[1]) + as.double(x[3])
## [1] 4

次のように,as.numeric() でも同じ結果が得られます。

as.numeric(x[1]) + as.numeric(x[3])
## [1] 4

2.2.1.1 欠損値

データがない部分のことを欠損値と言います。 数値の欠損値は NA で表します。 例えば,アンケート調査を実施して,ある回答者がある問の選択問題に対して解答をしていない場合,そこに - を入力してはいけません。 そこには,何も入力しないのが正しいデータ作成の方法です。 Microsoft Excelでデータ入力する場合は,そのセルには何も入力せずに次の入力に移ってください。 ただし,Rでデータ作成する場合,次のようにするとエラーが返ってきます。

c(1, 2, , 4, 5)

このため,欠損値には NA と書いてください。

c(1, 2, NA, 4, 5)

CSVファイルなどをRで読み込むときに欠損値があると,その部分がデフォルトでは NA に置き換わります。 ここで,次のようにするとエラーが返ってきます。

c(1, 2, -, 4, 5)

また,次のようにすると全体が文字列になります。

c(1, 2, "-", 4, 5)

一方,アンケート調査で,文章で回答してもらう問に対して無回答だった場合,そこに "" を入力してください。 Microsoft Excelでデータ入力する場合は,そのセルには何も入力せずに次の入力に移ってください。 CSVファイルなどをRで読み込むときに欠損値があると,その部分がデフォルトでは "" に置き換わります。

c("テニスが好き", "バレーボールをやってた", NA, "野球が苦手", "サッカーが得意")

これだとエラーは返ってきませんが,あまりよい方法ではありません。 この場合,次のようにしてください。

c("テニスが好き", "バレーボールをやってた", "", "野球が苦手", "サッカーが得意")

NA に似たものに NULL があります。 NULL はデータの欠損値には使いません。 NULL には例えば次のような使い方があります。

x <- NULL

2.2.2 名前付きベクトル

名前付きベクトルというものがあります。 辞書のような働きをします。

x <- c("リンゴ", "みかん", "リンゴ", "みかん", "バナナ", "みかん", "リンゴ")
y <- table(x)

このときの table() の返り値は名前付きベクトルです。 table(x)x の中にある文字列の種類ごとに,その文字列が何回出現するかを数えています。

y
## x
## バナナ みかん リンゴ 
##      1      3      3

ここで,みかんの出現回数を知りたい場合は,次のようにします。

y["みかん"]
## みかん 
##      3

ここで,y[2] としても同じ結果が得られます。 ただし,みかんが何番目にあるかを知るためには,y の中身を確認しなければなりません。 一方,名前付きベクトルを使う場合は,y の中身を確認する必要はなく,確実にみかんの出現回数を出力できます。

2.2.3 行列

Rは行列計算が高速であることが特徴のひとつです。 また,ここには書きませんが,行列を用いた数式の表記は簡潔です。

行列は以下のようにして作成します。

matrix(1:12, nrow = 4)
##      [,1] [,2] [,3]
## [1,]    1    5    9
## [2,]    2    6   10
## [3,]    3    7   11
## [4,]    4    8   12

nrow は行の数です。 行列の要素の数は,nrow の値で割り切れなければなりません。 列の数 ncol を指定しても構いません。

行列の外側の []で囲まれた部分に注目してください。 [], と数字によって,そこが行列の何行目か,あるいは,何列目かが分かります。 [行, 列] という関係になっています。

行列はMicrosoft Excelで見慣れたワークシートに似ています。 しかし,そうではなく,数学で出てくる行列そのものだと理解してください。 行列の要素は [] を用いて取り出します。 例えば,1行2列の要素は次のようにして取り出します。

x <- matrix(1:12, nrow = 4)
x[1, 2]
## [1] 5

行は次のようにして取り出します。

x[2, ]
## [1]  2  6 10

列は次のようにして取り出します。

x[, 3]
## [1]  9 10 11 12

ここで示した法則に従ってスペースを入れることを忘れないようにしてください。 スペースを入れずに,x[2,] としても x[,3] 同じ結果が得られます。 しかし,スペースがないと,人間がコードを読むときに,分かりにくくなります。

2.2.3.1 Tips

行列はベクトルを折り畳んだようなものであると理解しておくと役に立つことがあります。 次の結果を比較して,行列がベクトルであることを理解してください。

matrix(1:12, nrow = 4)[5]
## [1] 5
matrix(1:12, nrow = 4, byrow = TRUE)[5]
## [1] 2

次のコマンドが FALSE を返すように,行列はベクトルではありません。

is.vector(matrix(1:12, nrow = 4))
## [1] FALSE

通常のデータ分析で行列を扱う機会は少ないかもしれません。

2.2.4 データフレーム

データフレームには行と列が存在する点では,行列に似ています。 しかしながら,行列とは違い,各列を異なる型にすることができることから,行列よりも柔軟なデータ構造となります。 それぞれの列は同じ型でなければなりません。

データフレームはMicrosoft Excelでよく見る表そのようなものだと理解して構いません。 read.csv() で読み込んだオブジェクトは,データフレームです。

Rは最初から多くのデータセットが使える状態になっています。 サンプルとしてよく使われるデータセットに iris があります。 iris の中身は,iris と入力するだけで表示されます。

iris

データフレームの全体を表示させることなく,データフレームの構造を知りたいときは,最初の数行を表示させるコマンドを使うのが便利です。

head(iris)
##   Sepal.Length Sepal.Width Petal.Length Petal.Width Species
## 1          5.1         3.5          1.4         0.2  setosa
## 2          4.9         3.0          1.4         0.2  setosa
## 3          4.7         3.2          1.3         0.2  setosa
## 4          4.6         3.1          1.5         0.2  setosa
## 5          5.0         3.6          1.4         0.2  setosa
## 6          5.4         3.9          1.7         0.4  setosa

同じように,最後の数行を表示させることもできます。

tail(iris)
##     Sepal.Length Sepal.Width Petal.Length Petal.Width   Species
## 145          6.7         3.3          5.7         2.5 virginica
## 146          6.7         3.0          5.2         2.3 virginica
## 147          6.3         2.5          5.0         1.9 virginica
## 148          6.5         3.0          5.2         2.0 virginica
## 149          6.2         3.4          5.4         2.3 virginica
## 150          5.9         3.0          5.1         1.8 virginica

途中の行を表示させたい場合は,行番号を指定します。

iris[100:105, ]
##     Sepal.Length Sepal.Width Petal.Length Petal.Width    Species
## 100          5.7         2.8          4.1         1.3 versicolor
## 101          6.3         3.3          6.0         2.5  virginica
## 102          5.8         2.7          5.1         1.9  virginica
## 103          7.1         3.0          5.9         2.1  virginica
## 104          6.3         2.9          5.6         1.8  virginica
## 105          6.5         3.0          5.8         2.2  virginica

iris はオブジェクトであり,次のコマンドで確かめられるように,データフレームです。

is.data.frame(iris)
## [1] TRUE

データフレームの構造を知りたい場合は,次のようにします。

str(iris)
## 'data.frame':    150 obs. of  5 variables:
##  $ Sepal.Length: num  5.1 4.9 4.7 4.6 5 5.4 4.6 5 4.4 4.9 ...
##  $ Sepal.Width : num  3.5 3 3.2 3.1 3.6 3.9 3.4 3.4 2.9 3.1 ...
##  $ Petal.Length: num  1.4 1.4 1.3 1.5 1.4 1.7 1.4 1.5 1.4 1.5 ...
##  $ Petal.Width : num  0.2 0.2 0.2 0.2 0.2 0.4 0.3 0.2 0.2 0.1 ...
##  $ Species     : Factor w/ 3 levels "setosa","versicolor",..: 1 1 1 1 1 1 1 1 1 1 ...

データフレームを90度右に回転して反転させた表示になっていることに気づきましたか? iris の1列目 Sepal.Length が一番上に表示されています。 iris の2列目は2行目というように順番に表示されます。

また,データフレームの列ごとにデータの型(の省略形)が表示されることが分かります。 すなわち,データフレームのどの列もデータの型は1つしか認められていません。 違う型の行を追加しようとすると,エラーになるか警告が表示されます。

行の数と列の数は次のコマンドで取得できます。

dim(iris)
## [1] 150   5

この情報は,str(iris) の1行目に表示されるものと同じです。

なお,データフレームを Excel のように表示したい場合は,次のコマンドを実行します。

View(iris)

macOS では XQuartz が起動します。 R に慣れるまで,データフレームを Excel のような表示にした方が分かりやすい場合は View() を使ってください。 そのうち,必要なくなると思います。

2.2.4.1 データフレームの列

データフレームそのものを分析に使うこともできますが,必要な列を取り出して,分析に使うのが一般的です。 そこで,データフレームの列を取り出す方法をいくつか説明します。 なお,データフレームの進化したものに,tibble があります。 tibbleはデータフレームとほとんど同じように扱えますが,データフレームとは挙動が若干異なりますので,違うものと考えてください。 ちなみに,read_excel() で読み込んだオブジェクトは,tibbleです。 tibbleは Tidyverse の一部分(最も重要な部分)を構成します。

データフレームの列を取り出す場合,左から何列目であるかを数値で指定することができます。 次のコマンドにより,データフレームの列をベクトルとして取り出すことができます。

iris[, 1]

返り値をデータフレームとして保ちたければ,次のようにします。

iris[1]

次のようにすると,左から1列目をベクトルとして取り出せます。

iris[[1]]

このことから,iris[, 1]iris[[1]] は同じ結果が得られることが分かります。

データフレームの左から何列目かという情報は,対話的にRを使う場合は便利なときもありますが,データフレームの構造を事前に正確に把握しておかなければならず,またデータフレームの列が変わった場合,何列目かをわざわざ数え直さなければなりません。 こうした作業は面倒だということもありますが,それ以上に,間違う可能性があります。 列を取り出す際,データフレームの左から何列目かという情報ではなく,列名で指定する方が間違いが少なくなるでしょう。 irisSepal.Length 列を取り出したい場合は,次のように $ で繋ぎます。

iris$Sepal.Length

列名が日本語の場合など,次のようにしなければエラーが返ってくることがあります。

iris$`Sepal.Length`

日本語の他にも,列名に () が使われている場合は,`` で括らなければエラーが返ってきます。 返り値をデータフレームとして保ちたければ,次のようにします。

iris["Sepal.Length"]

このとき,"" をつけなければエラーが返ってきます。 ここで,"" の中は文字列として扱われるため,`` で括る必要はありません。

iris[Sepal.Length]
## Error:
## ! オブジェクト 'Sepal.Length' がありません

このとき,Sepal.Length という名前のオブジェクトを探しに行き,それがないためエラーを返しています。 次のようにすると,ベクトルとして取り出せます。

iris[, "Sepal.Length"]

また,次のようにしても同じ結果が得られます。

iris[["Sepal.Length"]]

ここで,列名を知るにはどうすればよいでしょうか。 str() で知ることができますが,str() だと情報が多いです。 データフレームの列名のみを得るには,次のコマンドを用います。

names(iris)
## [1] "Sepal.Length" "Sepal.Width"  "Petal.Length" "Petal.Width"  "Species"

これは次のようにしても同じです。

colnames(iris)
## [1] "Sepal.Length" "Sepal.Width"  "Petal.Length" "Petal.Width"  "Species"

次に,複数の列を取り出してみます。 irisSepal.Length 列と Sepal.Width 列を取り出すには,次のようにします。

iris[, c("Sepal.Length", "Sepal.Width")]

次のようにしても同じ結果が得られます。

iris[c("Sepal.Length", "Sepal.Width")]

データフレームから複数列を取り出す場合,返り値はベクトルではなく,必ずデータフレームになります。 このため,$[[]] は使えません。

カンマ , を使って列名を指定する場合,c() のベクトルの長さによって,返り血の型が変わることに気づいたでしょうか。 ベクトルの長さが1の場合,返り値はベクトルになります。 これを避けるために,次のように drop = FALSE を指定することがあります。

iris[, "Sepal.Length", drop = FALSE]

このようにすると,たとえ列が1つであっても,ベクトルではなく,データフレームとしての返り値が得られます。

2.2.4.2 データフレームの列

データフレームは,data.frame() で作成します。 データフレーム作成時に注意すべきことは,各列の長さを合わせるということです。

data.frame(year = 2021:2023, value = c("多", "少", "多"))

各列の長さが揃わないときは,短い列を繰り返してデータフレームが作成されます。

data.frame(year = 1991:2020, value1 = 1:30, value2 = NA, value3 = c("東", "西", "南"), value4 = 1:5)

この繰り返しは短い列が長い列に等しくなるまで行われ,揃わない場合はエラーが返ってきます。

data.frame(year = 1991:2020, value1 = 1:30, value2 = NA, value3 = c("東", "西", "南"), value4 = 1:4)

2.2.5 リスト

リストはさまざまなオブジェクトを入れることのできる,引き出しだと説明されることがあります。 さまざまなオブジェクトをリストに入れることができます。 データフレームのように,各列の要素の数を揃える必要はありません。 Pythonでいう辞書のようなものです。

リストはさまざまな形を取りますが,実践的には,複数のデータフレームを要素とできる点が便利です。

x <- list()

また,関数の返り値がリストとなることがあります。 例えば,データフレームをある列(ファクター)に従って分割したい場合,split() を用います。

x <- split(iris, iris$Species)
x[[1]]
x[["virginica"]]

リストは,Excelファイルにたとえることもできます。 Excelの1つのファイルの中に複数のシートがありますよね。 Rのリストも同じように,複数のオブジェクト(Excelのシートのようなもの)が入っていると考えると理解しやすいです。 リストの中には,データフレームだけでなく,ベクトルや行列,さらには他のリストも入れることができます。

2.3 特殊記号

2.3.1 コメント

# で始まる行はコメントです。 行の途中に # がある場合は,そこから右,改行までの文字がコメントとみなされます。 Rはコメントを無視します。 コメントは人間が読んで理解できるようなことを書くのに重宝します。 Rはコメントを無視するため,そこには何を書いても問題ありません。

例えば,コードを書き換える場合を想像してみてください。 新しいコードに問題があったときに,古いコードを復活させるかもしれず,残しておきたい,しかし,古いコードは実行したくないというときに,古いコードの先頭にコメントを付けることがあります。 他には,「このコードは一部の人のみ実行してください」や「このコードは実行しなくてもよい」といった意味で使用することもあります。

2.3.2 セミコロン

通常,Rでは1行に複数のコマンドを書きません。 ただし,1行に複数のコマンドを書くこともできます。 何らかの理由により,1行に複数のコマンドを書きたい場合は,次のように ; で繋げます。

x <- 1:100; sum(x)
## [1] 5050

ただし,こうしたからといって処理速度が速くなることはありません。 一方,人間がコードを読むときに,コードが詰まって書かれていると読みづらくなるため,基本的に1行に複数のコマンドは書かないことが多いです。

なお,; を使って書くと,コマンドと返り値の順番に変化がもたらされます。

sum(x)
## [1] 5050
mean(x)
## [1] 50.5

; のない場合とある場合とで,コマンドと返り値が表示される順番に違いがあることに注目してください。

sum(x); mean(x)
## [1] 5050
## [1] 50.5

返り値がまとまってほしいときに便利ですが,そうなってほしいことは滅多にありません。

2.3.3 評価と同時に返り値を表示

コマンドを実行して,返り値を得ることを評価と呼びます。 このとき,同時に,その返り値を表示したい場合,コマンド全体を () で括ります。

(x <- 10)
## [1] 10

関数の () とは異なり,全体を () で括ります。 これは次のようなコマンドを実行するのと同じことです。

x <- 10
x
## [1] 10

このように冗長に書くよりも,() を使った方が分かりやすいことがたまにあります。

2.4 入門書

2.4.1 無料

奥村先生による 統計・データ解析 は大変参考になります。 時間をかけてじっくり読むとともに,自分のパソコンで同じようにできるか確かめてください。

また,Posit Cloud にある Posit Primers は時間をかけて読む価値がありそうです。

Posit Cheat Sheets

チートシートの日本語訳がここからダウンロードできます(ページ右側の Downloadボタンをクリック)。

2.4.2 有料

J.D. Long and Paul Teetor(2020)『Rクックブック 第2版』オライリー・ジャパンは,Rの基本的な使い方が分かりやすく説明されています。 情報量が多いため,じっくり読む価値があります。

2.5 今回出てきた関数の整理

型の確認

typeof()
mode()
class()

数値

is.numeric()# 数値かどうか
is.double()# 数値かどうか
is.integer()# 整数かどうか
as.numeric()# 数値に変換
as.double()# 数値に変換
as.integer()# 整数に変換

文字列

is.character()# 文字列かどうか
as.character()# 文字列に変換
paste()# 文字列をくっつける。文字列でないば場合は文字列に変換してからくっつける
paste0()# paste() の引数が sep = ""

ファクター

is.factor()# ファクターかどうか
as.factor()# ファクターに変換。引数 levels や ordered は指定できない
factor()# ファクターを作成
levels()# ファクターの水準を取り出す

行列

is.matrix()# 行列かどうか
as.matrix()# 行列に変換
matrix()# 行列を作成

データフレーム

is.data.frame()# データフレームかどうか
as.data.frame()# データフレームに変換
data.frame()# データフレームを作成
str()# データフレームの構造を確認
head()# データフレームの最初の数行を表示
tail()# データフレームの最後の数行を表示
nrow()# 行数を取得
ncol()# 列数を取得
dim()# 行数と列数を取得
names()# 列名を取得
colnames()# names()と同じ
rownames()# 列名を取得
row.names()# rownames()と同じ

リスト

is.list()# リストかどうか
list()# リストを作成
unlist()# リストを解体

その他

t()# 転置
table()# 出現回数を数える
split()# データフレームをファクターに従って分割
View()# データフレームをExcelのように表示。普通は使わない

2.6 練習問題

  1. 次のオブジェクト x を文字列に変換しなさい。
x <- 2015:2025
  1. 次のオブジェクト x をファクターに変換しなさい。
x <- c(
  "松山市", "今治市", "宇和島市", "八幡浜市",
  "新居浜市", "西条市", "大洲市", "伊予市",
  "四国中央市", "西予市", "東温市"
)
  1. 次のオブジェクト y を数値に変換しなさい。
x <- c("2", "1", "5", "4", "3")
y <- factor(x, level = x)
  1. 次のオブジェクト x から NA を除いて平均を求めなさい。
x <- c(1, 2, NA, 4, NA, 6)
  1. 次のオブジェクト x を,水準の順序を「小 < 中 < 大」に設定したファクターに変換しなさい。
x <- c("中", "小", "大", "中", "大", "小")
  1. 次のリスト xy のそれぞれから松山市の人口の値を取り出しなさい。
a <- data.frame(
  id = c("382019", "382027", "382035"),
  city = c("松山市", "今治市", "宇和島市"),
  region = c("中予", "東予", "南予"),
  pop = c(510000, 160000, 80000)
)
x <- split(a, a$region)

y <- list(
  id = c("382019", "382027", "382035"),
  city = c("松山市", "今治市", "宇和島市"),
  region = c("中予", "東予", "南予"),
  pop = c(510000, 160000, 80000)
)
  1. 次のデータフレーム dscore 列を文字型から数値型に正しく変換し,平均を求めなさい。
d <- data.frame(score = c("10", "8", "", "9"))
  1. 次のコードの結果がどうなるか説明し,なぜそのようになるかを述べなさい。
c(1, 2, 3, 4) + c(10, 20)
  1. CSV Files から任意のCSVファイルをダウンロードして,R上のオブジェクト x に読み込みなさい。また,正しく読み込めたかを確かめなさい。
  • ヒント:CSVファイルを読み込む関数は,read.csv() です。
  1. 気象庁の次のWebサイトからCSVファイルをダウンロードして,オブジェクト temp に読み込んだ後,世界全体の年平均気温偏差の最大値と最小値を求めなさい。