データ型を組み合わせると、様々なデータの構造やクラスをつくることができます。本サイトでは、ベクトル、行列、データフレーム、リスト、因子型について見ていきます。これらのクラスは、空間分析においても活用されます。
ベクトル
#2で登場したRのコマンドは、全てベクトルを生成するものでした。ベクトルは最もよく使われるデータ構造であり、Rにおいて最も標準的な一次元の変数です。例えば、character()やlogical()といった関数を用いると指定した長さのベクトルが生成されます。または、vector()を用いて、指定した型で指定した長さのベクトルをつくることもできます。
・変換関数
as.vector()は、引数を指定した型のベクトルに変換します。デフォルトの型は論理値型ですが、値をベクトルに代入したとき、Rはそのベクトルに適したモードを探して使います。
・型チェック関数
is.vector()は、引数が指定した型やモードで、かつ名前以外の属性を持たない場合にTRUEを返し、それ以外の場合にはFALSEを返します。
# ベクトルを定義
# mode引数を指定しなければ、ベクトルかどうかのチェックのみ
vector(mode = "numeric", length = 8)
[1] 0 0 0 0 0 0 0 0
vector(length = 8)
[1] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
tmp <- data.frame(a = 10:15, b = 15:20)
is.vector(tmp)
[1] FALSE
as.vector(tmp)
$a
[1] 10 11 12 13 14 15
$b
[1] 15 16 17 18 19 20
R行列
matrix()は、指定したデータとパラメータから行列をつくります。パラメータは2次元のデータ構造であり、行数や列数が含まれます。そして、行と列のインデックスを使用して要素にアクセスし、行列演算や統計解析などの操作に便利です。
・変換関数
as.matrix()は、引数を行列に変換します。
・型チェック関数
is.matrix()は、引数が行列かどうかをチェックします。
# matrix()関数を使用して、指定した列数(ncol)と行数(nrow)の空の行列を作成します。
# 下記コードでは、列数が2で、行数が0の空の行列が作成されます。
matrix(ncol = 2, nrow = 0)
[,1] [,2]
# matrix() 関数を使用して、1から6までの整数を要素とする1列の行列を作成します。
# デフォルトでは、列数は自動的に計算され、行数は要素数に応じて調整されます。
matrix(1:6)
[,1]
[1,] 1
[2,] 2
[3,] 3
[4,] 4
[5,] 5
[6,] 6
# matrix() 関数を使用して、1から6までの整数を要素とする2列の行列を作成します。
# ncolパラメータを使用して列数を指定することで、行列の形状を制御します。
matrix(1:6, ncol = 2)
[,1] [,2]
[1,] 1 4
[2,] 2 5
[3,] 3 6
# as.matrix() 関数を使用して、ベクトルを行列に変換します。
# 下記コードでは、6から3までの整数を要素とする1列の行列が作成されます。
as.matrix(6:3)
[,1]
[1,] 6
[2,] 5
[3,] 4
[4,] 3
# is.matrix() 関数を使用して、オブジェクトが行列であるかどうかを判定します。
# as.matrix() 関数を使用してベクトルを行列に変換し、その結果が行列であるかどうかを判定します。
is.matrix(as.matrix(6:3))
[1] TRUE
Rこれらのコードは、行列の作成や変換、行列かどうかの判定など、行列を扱う際によく使用される一連の操作の例です。行列は、データの整理や計算、統計解析などに広く使用されるデータ構造です。
行と列に名前を付与
# matrix() 関数を使用して、要素が指定された順序で配置された3x3の行列を作成します。
# c(2023,1234,,,)は行列の要素を指定しており、c(3, 3)は行列のサイズを指定しています。
# byrow = TRUEは、要素が行ごとに指定されていることを示します。
flow <- matrix(c(2023, 1234, 777, 1234, 217, 456, 654, 120, 212), c(3, 3), byrow = TRUE)
# colnames() 関数を使用して、行列の列に名前を付けます。
# c("Leicester", "Livepool", "ElseWhere")は各列の名前を指定しています。
# rownames() 関数を使用して、行列の行に名前を付けます。
# c("Leicester", "Livepool", "ElseWhere")は各行の名前を指定しています。
colnames(flow) <- c("Leicester", "Livepool", "ElseWhere")
rownames(flow) <- c("Leicester", "Livepool", "ElseWhere")
# 上記のコードで作成した行列"flow"を表示します。
flow
# 行列は、要素が指定された通りに配置され、列と行にはそれぞれ名前が付けられています。
Leicester Livepool ElseWhere
Leicester 2023 1234 777
Livepool 1234 217 456
ElseWhere 654 120 212
# rowSums() 関数を使用して、行列の各行の要素の合計を計算し、新しいベクトル"outflows"に代入します。
# rowSums() 関数は、行列の各行の要素を足し合わせる操作を行います。
outflows <- rowSums(flow)
# 上記のコードで作成したベクトル"outflows"を表示します。
outflows
# outflowsベクトルには、各行の要素の合計が格納されています。
Leicester Livepool ElseWhere
4034 1907 986
R*データが行列でない場合は、rownames()やcolnames()ではなくnames()なので注意しましょう。
# ベクトル z を作成します。
z <- c(4, 5, 6)
# names() 関数を使用して、ベクトルの要素に名前を付けます。
# c("Newcastle", "London", "Manchester") は、各要素に対応する名前を指定しています。
names(z) <- c("Newcastle", "London", "Manchester")
# ベクトル z を表示します。
z
# ベクトルの各要素には、先程指定した名前が付けられています。
Newcastle London Manchester
4 5 6
R上記の一連の流れでは、ベクトルの作成、要素に名前を付けるという操作が行われています。名前付きのベクトルを使用することで、データの要素に意味を持たせることや、要素に対して直感的なアクセスが可能になります。
因子型
因子型はカテゴリカルデータを扱うのに便利です。カテゴリカルデータとは、データの値は全て決められたクラスのどれかに当てはまるようなデータを指します。地理情報分析では、地理データ中の多くの地物が離散的なクラスでラベル付けされています。例えば、順序付けによって傾向や構造についての推論(高低、良し悪しなど)が可能になります。また、データから一部を取り出す際や、得られた分析結果を解釈する際にも役立ちます。
順序付き因子型
デフォルトでは因子型に順序は付与されませんが、ordered()を使うと順序を付けることができます。
# factor() 関数を使用して、文字列ベクトルを因子型に変換します。
# c("High", "Low",,,) は文字列の要素を持つベクトルです。
# levels パラメータを使用して因子型の水準(レベル)を指定します。
income <- factor(c("High", "Low", "High", "Low", "High", "High", "Medium", "Low", "Medium"), levels = c("Low", "Medium", "High"))
# 因子型のベクトル income と文字列 "Low" の比較を行います。
# 下記比較では、因子型と文字列型の比較が行われます。
income > "Low"
# しかし、因子型と文字列型の比較は意味がないため、結果は NA (Not Available) となります。
# ワーニングメッセージが表示され、因子型と文字列型の比較の意味のなさについて警告されます。
[1] NA NA NA NA NA NA NA NA NA
Warning message:
In Ops.factor(income, "Low") : ‘>’ not meaningful for factors
# ordered() 関数を使用して、文字列ベクトルを順序付き因子型に変換します。
# c("High", "Low",,,) は文字列の要素を持つベクトルです。
income <- ordered(c("High", "Low", "High", "Low", "High", "High", "Medium", "Low", "Medium"), levels = c("Low", "Medium", "High"))
# 順序付き因子型のベクトル income と文字列 "Low" の比較を行います。
# 順序付き因子型では、水準間の大小関係を保持しているため、比較が有効になります。
income > "Low"
# 各要素と "Low" の比較結果が返され、論理値ベクトルが生成されます。
[1] TRUE FALSE TRUE FALSE TRUE TRUE TRUE FALSE TRUE
R上記一連の流れでは、因子型と順序付き因子型の作成、要素との比較の操作が行われています。因子型は、カテゴリカルデータを表現する際に使用され、順序付き因子型は順序があるカテゴリカルデータを表現します。ここから、順序付けは水準を定義することによって暗黙的に決まり、順序に関連する関数を適用できることがわかります。
リスト
リストは、これまでに紹介したデータ型(文字列型、数値型、論理値型)、それに関連するクラスはいずれも、全ての要素が同じデータ型であることが要求されるものでした。
リストはそういった制約がなく、異なるデータ型の要素を持つことができる複数のオブジェクトをまとめるためのデータクラスです。様々な要素のためのスロットを持っており、順序のある要素集合です。リストを使うと、様々なデータ型を1つのデータ構造に詰め込むことができ、任意の位置の要素を角括弧2つ( [ [ ] ] )で取り出すことができます。
# list() 関数を使用して、複数の要素を持つリストを作成します。
# リスト内の要素はカンマで区切られ、ダブルクォーテーションで囲まれた文字列やベクトル、行列などのデータが含まれます。
tmp.list <- list("George Lucas", c(1977, 2005), "director", matrix(c(7, 4, 2, 3), c(2, 3)))
# 作成したリスト tmp.list を表示します。
# リストは [[]] で囲まれた番号で要素にアクセスします。
tmp.list
[[1]]
[1] "George Lucas"
[[2]]
[1] 1977 2005
[[3]]
[1] "director"
[[4]]
[,1] [,2]
[1,] 7 2
[2,] 4 3
# リスト tmp.list の4番目の要素にアクセスします。
tmp.list[[4]]
# 4番目の要素は行列であり、行列の内容が表示されます。
[,1] [,2]
[1,] 7 2
[2,] 4 3
R上記の一連の流れでは、list()
関数を使用してリストを作成し、異なる種類のデータを要素として含めています。リストは複数のオブジェクトをまとめて扱うためのデータ構造であり、異なるデータ型の要素を含むことができます。list()は、その引数からなるリストを返します。引数の指定の仕方によって各値に名前を紐づけることもできます。
また、リスト内の要素には [[]]
を使用してアクセスすることができます。特定の要素を取り出して個別に操作したり、データの抽出や処理に利用することができます。上記の例では、4番目の要素である行列を tmp.list[[4]]
として取り出して表示しています。
・変換関数
as.list()は、引数をリストに変換します。例えば、因子型ベクトルに渡すと、1要素の因子型ベクトルのリストに変換し、指定しなかった属性は全て取り除きます。
・型チェック関数
is.list()は、引数がリストである場合にのみTRUEを返します。
# list() 関数を使用して、名前付きのリスト film を作成します。
# リスト内の要素は name = "George Lucas"、start.year = 2005、position = "Film director"、Film.name = "StarWars" のように名前と値のペアで指定されます。
film <- list(name = "George Lucas", start.year = 1977, position = "
Film director", Film.name = "StarWars")
# 作成したリスト film を表示します。
film
# リストの要素は $ 記号を使って名前でアクセスします。
$name
[1] "George Lucas"
$start.year
[1] 2005
$position
[1] "Film director"
$Film.name
[1] "StarWars"
Rappend()を使うとリスト同士を結合できます。またlapply()は関数をリストの各要素に適用します。
# append() 関数を使用して、リスト tmp.list に新しい要素を追加します。
# 追加する要素は list(c(8, 7, 10, 2)) であり、ベクトルをリストの要素として含みます。
append(tmp.list, list(c(8, 7, 10, 2)))
[[1]]
[1] "George Lucas"
[[2]]
[1] 1977 2005
[[3]]
[1] "director"
[[4]]
[,1] [,2]
[1,] 7 2
[2,] 4 3
[[5]]
[1] 8 7 10 2
# lapply() 関数を使用して、リスト tmp.list の2番目の要素に対して関数 is.numeric() を適用します。
# lapply() 関数は、リストの各要素に同じ操作を適用し、結果をリストとして返します。
lapply(tmp.list[[2]], is.numeric)
[[1]]
[1] TRUE
[[2]]
[1] TRUE
# lapply() 関数を使用して、リスト tmp.list の各要素の長さを計算します。
# length() 関数は、ベクトルやリストの要素数を返します。
lapply(tmp.list, length)
[[1]]
[1] 1
[[2]]
[1] 2
[[3]]
[1] 1
[[4]]
[1] 4
R上記の一連の流れでは、リストに要素を追加し、リストの要素を操作しています。
append()
関数を使用して、リストtmp.list
に新しい要素が追加されます。結果として、リストの要素数が1つ増えています。lapply()
関数を使用して、リストtmp.list
の2番目の要素に対して関数is.numeric()
を適用します。結果は、2番目の要素の各要素が数値であるかどうかを示す真偽値のリストとなります。lapply()
関数を使用して、リストtmp.list
の各要素の長さを計算します。結果は、各要素の要素数(長さ)を示す数値のリストとなります。
これらの操作により、リストの要素の追加や要素内のデータの特性を調べることができます。リストは異なるデータ型やデータ構造の要素をまとめて扱うための便利なデータ構造でした。なお、行列にlength()を適用した結果はリストの中でも同じで、要素数の合計になっています。
独自のクラスを定義する
Rでは独自のデータ型を定義して、コンソールへの表示や描画などの挙動を指定することができます。例として、plot()を使うことで従来型のグラフだけでなく、地理データを地図として描画できます。
# starwarsという名前のリストを作成します。このリストには、"George Lucas"という名前の監督、1977年の開始年、"Director"という職位が含まれています。
Lucasfilm <- list(name = "George Lucas", start.year = 1971, position = "Directer")
# class(starwars) <- "Lucasfilm"の行でstarwarsリストのクラスを"Lucasfilm"に設定します。
# これにより、starwarsオブジェクトは"Lucasfilm"というクラスに属することになります。
class(Lucasfilm) <- "starwars"
# print.Lucasfilmという関数を定義します.
# この関数は、"Lucasfilm"クラスのオブジェクトを引数として受け取ります。関数の中では、cat関数を使ってオブジェクトの名前、開始年、職位を表示しています。
print.starwars <- function(x) {
cat("Name: ", x$name, "\n")
cat("Start Year: ", x$start.year, "\n")
cat("Job Title: ", x$position, "\n")
}
# print(starwars)という行で、starwarsオブジェクトをprint関数で表示します。
print(Lucasfilm)
Name: George Lucas
Start Year: 1971
Job Title: Directer
Rリストの要素のクラス
新しいユーザ定義のクラスのオブジェクトは、変数に代入することができます。例えとして、以下にstaffオブジェクトを作る関数を定義しています。
# new.starwarsという関数を定義します。この関数は、name、開始年、職位の3つの引数を受け取ります。
# 関数内では、これらの引数を使用して新しいリスト(result)を作成します。
new.starwars <- function(name, year, post) {
result <- list(name = name, start.year = year, position = post)
class(result) <- "starwars"
return(result)
}
# leics.uniという名前の長さ3のリストを作成します。
leics.uni <- vector(mode = "list", 3)
leics.uni[[1]] <- new.starwars("The Mandalorian", 2019, "spin off")
leics.uni[[2]] <- new.starwars("The Book of Boba Fett", 2021, "spin off")
leics.uni[[3]] <- new.starwars("Obi-Wan Kenobi", 2022, "spin off")
# leics.uniリストを表示すると、3つの要素が含まれています。
leics.uni
[[1]]
Name: The Mandalorian
Start Year: 2019
Job Title: spin off
[[2]]
Name: The Book of Boba Fett
Start Year: 2021
Job Title: spin off
[[3]]
Name: Obi-Wan Kenobi
Start Year: 2022
Job Title: spin off
R