ここでは、読み込んだデータを整形したり加工したりするのによく使う関数を紹介します。なお、ここではデータフレームを念頭においています。

使用するデータ

説明で使用するデータフレームとして、Rにもともと組み込まれているirisデータを使用します。

names(iris)
## [1] "Sepal.Length" "Sepal.Width"  "Petal.Length" "Petal.Width" 
## [5] "Species"
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 ...
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

データフレームの要素へのアクセス

データフレーム内の要素へアクセス(選択・指定)する方法を紹介します。これが基本かつ最重要です。

データハンドリングは「操作したいターゲットを指定」することが第一歩となります。操作したいターゲットを指定できるのであれば、あとはそれを処理してしまえばいいのです。逆にこれができないと何もできないこととなります。Excelなどと違い、Rは関数で指定していくため、最初に躓くポイントです。

行番号・列番号を使ったアクセス

行番号を指定してアクセスするには、以下のようにやります:

iris[3,]  # 3行目(全部)にアクセス
##   Sepal.Length Sepal.Width Petal.Length Petal.Width Species
## 3          4.7         3.2          1.3         0.2  setosa

データフレーム名のすぐ後に角括弧[,]をつけ、その中で数値を指定するとその要素へアクセスできます。[行,列]とイメージしてください。

列番号を指定してアクセスするには、以下のような感じになります:

x <- iris[, 2] # irisの2列目にアクセス
head(x, 5)  # 長いので上から5つ分取り出す
## [1] 3.5 3.0 3.2 3.1 3.6

考え方は行番号で説明したのと同様です。もちろん両方同時に指定してアクセスもできます:

iris[3, 2] # 20行目の2列目にアクセス
## [1] 3.2

まずは行と列になれましょう。

複数の行番号(や列番号)をまとめてアクセス

iris[21:24,]  # 21行目から24行目へアクセス
##    Sepal.Length Sepal.Width Petal.Length Petal.Width Species
## 21          5.4         3.4          1.7         0.2  setosa
## 22          5.1         3.7          1.5         0.4  setosa
## 23          4.6         3.6          1.0         0.2  setosa
## 24          5.1         3.3          1.7         0.5  setosa

行番号を:でつなぐと連番を持ってきます。なお、この:は数値の連番が入ったベクトルを返す演算子です:

3:8
## [1] 3 4 5 6 7 8

つまり、[ , ]では数値ベクトルを与えればその数値にアクセスしてくれるのです:

x <- iris[, c(2,5)] # 2列目と5列目へアクセス 
head(x, 5) # 長いので5行分
##   Sepal.Width Species
## 1         3.5  setosa
## 2         3.0  setosa
## 3         3.2  setosa
## 4         3.1  setosa
## 5         3.6  setosa

c(2,5)25がはいった数値ベクトルなので、2列目と5列目にアクセスするようになります。

もちろん、両方を同時に指定できます:

iris[21:24, c(2, 5)]
##    Sepal.Width Species
## 21         3.4  setosa
## 22         3.7  setosa
## 23         3.6  setosa
## 24         3.3  setosa

ある列(行)番号を除外してアクセス

「ある要素を除外する」という場合には、-を活用します:

iris[21:24,-5]  # 21-24行目から、5列目を除外
##    Sepal.Length Sepal.Width Petal.Length Petal.Width
## 21          5.4         3.4          1.7         0.2
## 22          5.1         3.7          1.5         0.4
## 23          4.6         3.6          1.0         0.2
## 24          5.1         3.3          1.7         0.5

行番号や列番号は正の整数しか存在しないため、-を負の値とはみなさす、このように処理してくれるんだと思います。:を使った連番では以下のようになります:

iris[21:24,-4:-5]  # 21-24行目から4,5列目を除外
##    Sepal.Length Sepal.Width Petal.Length
## 21          5.4         3.4          1.7
## 22          5.1         3.7          1.5
## 23          4.6         3.6          1.0
## 24          5.1         3.3          1.7

-4:-5-4と-5`が入った数値ベクトルを返してくるため、その2つが効果を発揮します。なお、数値ベクトルを準備してそれを除外することもできます:

iris[21:24, -c(2, 5)] #21-24行目から2列目と5列目を除外
##    Sepal.Length Petal.Length Petal.Width
## 21          5.4          1.7         0.2
## 22          5.1          1.5         0.4
## 23          4.6          1.0         0.2
## 24          5.1          1.7         0.5

おそらくは最後の例を基本に考えていたほうがいいでしょう。

変数名(列名)を使ってアクセス

通常、列番号ではなく変数名(列名)を使うことが多いかと思います。この場合、以下のように指定します:

x <- iris$Sepal.Width # irisのSepal.Widthにアクセス
head(x, 3) # 上から3行分
## [1] 3.5 3.0 3.2

データフレーム名$変数名で指定可能です。なおRStudioなら、この$を入力したら候補が出てきますので、選択が楽になるはずです。もしデータフレーム内の変数リストがほしい時はls()関数が便利です:

ls(iris)  #iris内の変数(オブジェクト)リストを出力
## [1] "Petal.Length" "Petal.Width"  "Sepal.Length" "Sepal.Width" 
## [5] "Species"

subset()関数を使ってアクセス

subset()はデータフレームから切り出してサブデータセットを作るイメージです。[ , ]で説明したような内容をスムーズに行なえます。

selectオプションで列番号指定

x <- subset(iris, select = 2:3) # irisから2:3列目を選択
head(x, 3) # xの3行分
##   Sepal.Width Petal.Length
## 1         3.5          1.4
## 2         3.0          1.4
## 3         3.2          1.3

subset()関数の第一引数にデータフレームを指定し、select=引数で列を指定します。考え方は上述の[,]と同様です。

変数名(列名)を使ってアクセス

x <- subset(iris, select = Sepal.Width) #irisからSepal.Widthを選択
head(x, 3)
##   Sepal.Width
## 1         3.5
## 2         3.0
## 3         3.2

selectに変数名を直接指定することも可能です。文字列("Sepal.Width"のようなもの)でもOKです。複数の列名を指定してアクセスも可能です:

x <- subset(iris, select = c(Sepal.Length,Sepal.Width))
head(x, 3)
##   Sepal.Length Sepal.Width
## 1          5.1         3.5
## 2          4.9         3.0
## 3          4.7         3.2

このように、select=にベクトルでもOKとなります。また、変数が並んでいるときなどは、以下のように:を使うこともできます:

x <- subset(iris, select = Sepal.Length:Petal.Length)
head(x, 3)
##   Sepal.Length Sepal.Width Petal.Length
## 1          5.1         3.5          1.4
## 2          4.9         3.0          1.4
## 3          4.7         3.2          1.3

irisデータはSepal.Lengthが1列目、Petal.Lengthは3行目にあるので、1列目から3列目まで持ってくるようになります。使いドコロとしては、心理尺度などでs101からs110までの変数が並んでいる場合、以下のようにアクセスすることが可能となります:

# hogeというデータフレームにs101からs110まで並んで入っているとします
subset(hoge, select = s101:s110)

また、除外する変数を変数名で指定することも可能です。考え方は[,]と同様で-を利用します:

x <- subset(iris, select = -c(Sepal.Length,Species))
head(x, 2)
##   Sepal.Width Petal.Length Petal.Width
## 1         3.5          1.4         0.2
## 2         3.0          1.4         0.2

これで除外できます。なお、指定する変数名は文字列ベクトルで与えることができるので、こんな感じで準備することもできます:

select_list1 <- paste("se", c(1, 3, 5, 8, 10), sep = "")
select_list1
## [1] "se1"  "se3"  "se5"  "se8"  "se10"

あるいは正規表現を使って、以下のように指定することもできたりします:

# ls(iris)でiris内の変数名を取得し、その中から「冒頭に"S"がある」ものを持ってくる
x <- subset(iris, select = grep("^S", ls(iris)))
head(x, 3)
##   Petal.Length Petal.Width Species
## 1          1.4         0.2  setosa
## 2          1.4         0.2  setosa
## 3          1.3         0.2  setosa

このあたりは結構応用的で難しく感じるかもしれません。そのうちでいいと思います。

レコード(行)に条件を指定してアクセス

条件を指定して、レコードを抽出することができます:

subset(iris, subset = Sepal.Width>4.0)
##    Sepal.Length Sepal.Width Petal.Length Petal.Width Species
## 16          5.7         4.4          1.5         0.4  setosa
## 33          5.2         4.1          1.5         0.1  setosa
## 34          5.5         4.2          1.4         0.2  setosa

subset = (条件式)で、その条件にマッチするレコード(行)にアクセスします。この場合、「Sepal.Widthが4より大きい行」を抽出してきます。もちろん上述の列を指定するselect=と同時に使えます:

subset(iris, select = 2:3, subset = Sepal.Width>4.0)
##    Sepal.Width Petal.Length
## 16         4.4          1.5
## 33         4.1          1.5
## 34         4.2          1.4

以上は>=で、以下は<=が演算子となります:

subset(iris, subset = Sepal.Width>=4.0)
##    Sepal.Length Sepal.Width Petal.Length Petal.Width Species
## 15          5.8         4.0          1.2         0.2  setosa
## 16          5.7         4.4          1.5         0.4  setosa
## 33          5.2         4.1          1.5         0.1  setosa
## 34          5.5         4.2          1.4         0.2  setosa

「~と等しい」という場合には==が演算子となります:

x <- subset(iris, subset = Species=="setosa")
head(x)
##   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

と等しくない(ではない)」という場合は、!=が演算子となります:

x <- subset(iris, subset = Species!="setosa")
x[sample(nrow(x), size = 10),] #ランダムに10行持ってくる
##     Sepal.Length Sepal.Width Petal.Length Petal.Width    Species
## 140          6.9         3.1          5.4         2.1  virginica
## 107          4.9         2.5          4.5         1.7  virginica
## 99           5.1         2.5          3.0         1.1 versicolor
## 131          7.4         2.8          6.1         1.9  virginica
## 52           6.4         3.2          4.5         1.5 versicolor
## 115          5.8         2.8          5.1         2.4  virginica
## 136          7.7         3.0          6.1         2.3  virginica
## 67           5.6         3.0          4.5         1.5 versicolor
## 82           5.5         2.4          3.7         1.0 versicolor
## 143          5.8         2.7          5.1         1.9  virginica

もし、「AまたはBのどちらかとマッチするもの」を取り出したい場合、%in%演算子を使います:

x <- subset(iris, subset = Species %in% c("setosa", "versicolor"))
x[sample(nrow(x), size = 10),] #ランダムに10行持ってくる
##    Sepal.Length Sepal.Width Petal.Length Petal.Width    Species
## 25          4.8         3.4          1.9         0.2     setosa
## 21          5.4         3.4          1.7         0.2     setosa
## 76          6.6         3.0          4.4         1.4 versicolor
## 30          4.7         3.2          1.6         0.2     setosa
## 2           4.9         3.0          1.4         0.2     setosa
## 15          5.8         4.0          1.2         0.2     setosa
## 89          5.6         3.0          4.1         1.3 versicolor
## 82          5.5         2.4          3.7         1.0 versicolor
## 33          5.2         4.1          1.5         0.1     setosa
## 22          5.1         3.7          1.5         0.4     setosa

条件が複数ある場合、ANDなら&でつなぎ、ORなら|でつなぎます:

subset(iris, subset = Sepal.Width>3.5 & Petal.Width>1.0)
##     Sepal.Length Sepal.Width Petal.Length Petal.Width   Species
## 110          7.2         3.6          6.1         2.5 virginica
## 118          7.7         3.8          6.7         2.2 virginica
## 132          7.9         3.8          6.4         2.0 virginica
subset(iris, subset = Sepal.Width>4.0 | Petal.Width>2.0)
##     Sepal.Length Sepal.Width Petal.Length Petal.Width   Species
## 16           5.7         4.4          1.5         0.4    setosa
## 33           5.2         4.1          1.5         0.1    setosa
## 34           5.5         4.2          1.4         0.2    setosa
## 101          6.3         3.3          6.0         2.5 virginica
## 103          7.1         3.0          5.9         2.1 virginica
## 105          6.5         3.0          5.8         2.2 virginica
## 106          7.6         3.0          6.6         2.1 virginica
## 110          7.2         3.6          6.1         2.5 virginica
## 113          6.8         3.0          5.5         2.1 virginica
## 115          5.8         2.8          5.1         2.4 virginica
## 116          6.4         3.2          5.3         2.3 virginica
## 118          7.7         3.8          6.7         2.2 virginica
## 119          7.7         2.6          6.9         2.3 virginica
## 121          6.9         3.2          5.7         2.3 virginica
## 125          6.7         3.3          5.7         2.1 virginica
## 129          6.4         2.8          5.6         2.1 virginica
## 133          6.4         2.8          5.6         2.2 virginica
## 136          7.7         3.0          6.1         2.3 virginica
## 137          6.3         3.4          5.6         2.4 virginica
## 140          6.9         3.1          5.4         2.1 virginica
## 141          6.7         3.1          5.6         2.4 virginica
## 142          6.9         3.1          5.1         2.3 virginica
## 144          6.8         3.2          5.9         2.3 virginica
## 145          6.7         3.3          5.7         2.5 virginica
## 146          6.7         3.0          5.2         2.3 virginica
## 149          6.2         3.4          5.4         2.3 virginica

文字列の部分一致も以下のように実行すればできます:

x <- subset(iris, subset = grepl("sa", iris$Species))
x[sample(nrow(x), 10),]
##    Sepal.Length Sepal.Width Petal.Length Petal.Width Species
## 25          4.8         3.4          1.9         0.2  setosa
## 34          5.5         4.2          1.4         0.2  setosa
## 4           4.6         3.1          1.5         0.2  setosa
## 16          5.7         4.4          1.5         0.4  setosa
## 48          4.6         3.2          1.4         0.2  setosa
## 1           5.1         3.5          1.4         0.2  setosa
## 35          4.9         3.1          1.5         0.2  setosa
## 41          5.0         3.5          1.3         0.3  setosa
## 24          5.1         3.3          1.7         0.5  setosa
## 46          4.8         3.0          1.4         0.3  setosa

詳細は省略します。。

データの操作

変数の変換(他の変数へ)

既存の変数に処理をして、他の変数へ出す場合は、transform()関数を使用します:

x <- transform(iris, kazu=Sepal.Width+5)
head(x,3)
##   Sepal.Length Sepal.Width Petal.Length Petal.Width Species kazu
## 1          5.1         3.5          1.4         0.2  setosa  8.5
## 2          4.9         3.0          1.4         0.2  setosa  8.0
## 3          4.7         3.2          1.3         0.2  setosa  8.2

第一引数に元となるデータフレーム、以降に新しい変換した変数を定義します。

変数の変換(更新)

先の新しい変数名を、既存の変数名にすると、その変数が上書きされて更新されます:

x <- transform(x, kazu=Sepal.Width+5)

基本、「元に戻す」という機能はないので、こういうデータハンドリングはコードをスクリプトに残すようにして履歴をたどれるようにしておいてください。

欠損値がある行の除去

サンプルとして、以下のデータフレームを準備します:

##   x1 y1
## 1  1 11
## 2  2 12
## 3  3 NA
## 4 NA 14
## 5  5 15

このデータフレームからNAを含む行を削除するには、以下のようにします:

x[complete.cases(x),]
##   x1 y1
## 1  1 11
## 2  2 12
## 5  5 15

分析に使う関数によっては、na.rm=という引数が使えることもあるので、各関数のヘルプを確認してください。

行和の算出

行和(横方向へ足し算)するときは、rowSums()関数を使用します:

x <- subset(iris, select = -Species)
head(x)
##   Sepal.Length Sepal.Width Petal.Length Petal.Width
## 1          5.1         3.5          1.4         0.2
## 2          4.9         3.0          1.4         0.2
## 3          4.7         3.2          1.3         0.2
## 4          4.6         3.1          1.5         0.2
## 5          5.0         3.6          1.4         0.2
## 6          5.4         3.9          1.7         0.4
head(rowSums(x))
##    1    2    3    4    5    6 
## 10.2  9.5  9.4  9.4 10.2 11.4

多くの場合、そのデータフレームに新たな列として追加したいでしょうから、以下のような感じになります:

x$rsum <- rowSums(x)
head(x)
##   Sepal.Length Sepal.Width Petal.Length Petal.Width rsum
## 1          5.1         3.5          1.4         0.2 10.2
## 2          4.9         3.0          1.4         0.2  9.5
## 3          4.7         3.2          1.3         0.2  9.4
## 4          4.6         3.1          1.5         0.2  9.4
## 5          5.0         3.6          1.4         0.2 10.2
## 6          5.4         3.9          1.7         0.4 11.4

上のx$rsumのように、存在しない変数に対してベクトルを放り込むと、新しくその変数(列)が作られます。

行平均の算出

行平均を算出するときは、rowMeans()関数を利用します。使い方はrowSums()と同様です:

x <- subset(iris, select = -Species)
head(x)
##   Sepal.Length Sepal.Width Petal.Length Petal.Width
## 1          5.1         3.5          1.4         0.2
## 2          4.9         3.0          1.4         0.2
## 3          4.7         3.2          1.3         0.2
## 4          4.6         3.1          1.5         0.2
## 5          5.0         3.6          1.4         0.2
## 6          5.4         3.9          1.7         0.4
head(rowMeans(x))
##     1     2     3     4     5     6 
## 2.550 2.375 2.350 2.350 2.550 2.850

実際の場合では、このような使い方になるかと:

x$rmean <- rowMeans(x)
head(x)
##   Sepal.Length Sepal.Width Petal.Length Petal.Width rmean
## 1          5.1         3.5          1.4         0.2 2.550
## 2          4.9         3.0          1.4         0.2 2.375
## 3          4.7         3.2          1.3         0.2 2.350
## 4          4.6         3.1          1.5         0.2 2.350
## 5          5.0         3.6          1.4         0.2 2.550
## 6          5.4         3.9          1.7         0.4 2.850

なお、rowSums()rowMeans()も文字列など計算できない変数が含まれているとエラーを出しますので注意してください。また、na.rm=オプションが使えますので、必要に応じて使ってください。

データフレームの結合

2つのデータフレームを準備します:

x <- data.frame(a=1:3,b=c("A","B","C"),c=11:13)
x
##   a b  c
## 1 1 A 11
## 2 2 B 12
## 3 3 C 13
y <- data.frame(a=2:4,b=c("B","C","D"),d=12:14)
y
##   a b  d
## 1 2 B 12
## 2 3 C 13
## 3 4 D 14

以降、これを使って説明します。

両方に含まれる列をキーとして結合

データフレームを結合するには、merge()関数を使用します:

merge(x,y)
##   a b  c  d
## 1 2 B 12 12
## 2 3 C 13 13

この場合、xyで共通する変数(この場合ab)をキー変数として、その2つが一致する行のみ取り出して結合させます。片方しかない列は、それぞれ残ることとなります。

両方を網羅して結合

データを落とすことなく結合させるには、all=TRUEという引数を与えます:

merge(x,y,all=TRUE)
##   a b  c  d
## 1 1 A 11 NA
## 2 2 B 12 12
## 3 3 C 13 13
## 4 4 D NA 14

この場合、2つのデータフレームで共通する列をキー変数として結合し、キー変数が一致しないレコード(行)は追加されます。なお値がない部分についてはNAが入ります。

データフレームに行を追加

データフレームに行を追加する場合、rbind()関数を使用します:

データフレームに列を追加

データフレームに列を追加する場合、cbind()関数を使用します:

パッケージを利用したデータハンドリング

最近では、このようなデータハンドリングは専用のパッケージを利用することが多くなっています。この方が効率的に処理でき、また処理が高速な場合が多いためです。

代表的なパッケージとして、dplyrパッケージがあります。またデータの縦・横変換などに効果を発揮するtidyrパッケージも有用です。この2つの関数の基本的な使い方については、以下のドキュメントを参照してください:

データハンドリング

ページのトップへ