U2. データ型とオブジェクト

ユニット概要

分類: 幹(全員必須)

依存関係: U0 → U1 → U2

学習目標:

  • ベクトル、リスト、データフレームの違いを理解する
  • 数値型、文字型、論理型、Factor型を使い分けられる
  • c(), seq(), rep()でベクトルを作成できる
  • [], [[]], $を使い分けて要素にアクセスできる
  • データの型を確認し、必要に応じて変換できる

事前知識: なぜデータ型が重要なのか

データとは何か

心理学では目に見えないものを研究対象とするため、心を持つと考えられる主体にたいして刺激を与え、その反応を見て「こうすれば(刺激)→ 心のせいで → こうなる(反応)」という因果を説明するためのモデルとして研究します。ここで刺激と反応は、研究対象である「心」の外にあって、観測できるものです。これをデータにします。

改めてデータとは何でしょうか。たとえば4人の研究対象者がいて、名前、性別、所持金などの情報を集めたとします。この中でデータとはいったい何を表すでしょうか。所持金は数字ですので、これだけがデータだ、と思ったら大間違いです。実は名前や性別もデータです。これらはすべて数値化し、データとして扱えるものです。

変数と尺度化

名前、性別、所持金などは人によって変わる数字です。人によって変わる数字のことを変数(variables)と言います。名前・性別・所持金は変数名であり、それがケースごとに「Aさん」「男性(male)」「15円」と変わるのです。

ここで15円はともかく、名前や性別は数字じゃないぞ?と思われるかもしれません。数字じゃないような実体であっても、これに数字を割り振るルールを決めて数字に置き換えていきます。このルールを決めることを尺度化(scaling)と言います。

たとえば性別は「女性(female)」を1に、「男性(male)」を2に置き換えることができます。名前に至っては、「Aさん」を1に、「Bさん」を2に、「Cさん」を3に、「Dさん」を4に置き換えることができます。

量的変数と質的変数

こうしてみていても、数字には2種類あることがわかります。

  • 量的変数(numeric variable): 本来の数字としての意味を持っているもの(所持金、年齢、身長など)。大小関係があり、計算が可能です。
  • 質的変数(categorical variable): 人や性質を分類するためのもので、数字に大小関係など量的な違いを表すものではありません。いわば質的な違いを表すための数字です(性別、血液型、都道府県など)。

「なんでも数字にして扱うが、数字には種類がある」ということに注意が必要です

計算機におけるデータ型

Rでは、値は大きく3つの種類を持ちます:

  1. 数値(numeric): 数字を数字として扱う。整数(integer)、実数(double)、複素数(complex)など。
  2. 文字列(character): シングルクォーテーション、あるいはダブルクォーテーションで渡されたものは文字列として扱う。
  3. 論理値(logical): TRUE(真)やFALSE(偽)。条件が成立したかどうか、スイッチのオン・オフのような表現をしたい時に使われる。

実際に値を付与する時に、どの種類で渡されているかに注意しましょう。たとえば1は数値としてあつかわれますが、"1"(クォーテーション付き)は文字として扱われます。計算機上は、クォーテーションで囲まれていない半角数字のみが数値として扱われます。

なぜデータ型が重要か

Rでデータ分析を行うとき、データの「型」を正しく理解することが不可欠です:

  • 数値型の変数には計算ができる(平均、標準偏差など)
  • 文字型の変数は計算できないが、ラベルやカテゴリとして使える
  • Factor型はカテゴリカルデータの分析に必須(t検定、分散分析など)

間違った型で保存していると、「平均が計算できない」「グループ分けができない」といった問題が起こります。このユニットでは、Rの基本的なデータ型とオブジェクトについて学びます。


ランクC: 基礎知識を確認しよう

2-C-1

ベクトルは同じ型の要素しか持てないが、リストは異なる型の要素を持つことができる。

これは正しいです。ベクトル(c(1, 2, 3))はすべての要素が同じ型(この場合は数値型)である必要があります。もしc(1, "hello", TRUE)のように異なる型を混ぜると、すべて文字型に変換されます。一方、リスト(list(1, "hello", TRUE))は異なる型の要素を保持できます。


2-C-2

次のコードを実行すると、xはどの型になりますか?

x <- c(1, 2, "3")

ベクトルは同じ型しか持てないため、数値と文字が混在すると、すべて文字型に変換されます。この例ではxc("1", "2", "3")という文字型ベクトルになります。class(x)で確認すると"character"が返ってきます。


2-C-3

リストの要素にアクセスするとき、[[]](二重括弧)と[](一重括弧)の違いは何ですか?

[[1]]は「リストの第1要素そのもの」を取り出します。一方、[1]は「第1要素を含む長さ1のリスト」を返します。

my_list <- list(a = 1:3, b = "hello")
my_list[[1]]  # 結果: 1 2 3 (ベクトル)
my_list[1]    # 結果: $a [1] 1 2 3 (リスト)

データ分析では、[[]]$で要素そのものを取り出すことが多いです。


2-C-4

Factor型の主な役割は何ですか?

Factor型は、カテゴリカル(質的)データを扱うための型です。たとえば性別(“男”, “女”)、学年(“1年”, “2年”, “3年”)などを表すのに使います。Rの統計関数(t.test(), aov()など)は、Factor型の変数をグループ分けの基準として認識します。文字型のままだと、これらの関数が正しく動作しないことがあります。


2-C-5

NANaNの違いは何ですか?

  • NA (Not Available): データが欠けている(測定されなかった、記録されなかった等)
  • NaN (Not a Number): 数学的に定義されない値(例: 0/0, Inf - Inf
x <- c(1, 2, NA, 4)       # データの3番目が欠測
y <- 0 / 0                # NaN(ゼロ割るゼロは定義されない)

is.na()はNA・NaN両方にTRUEを返しますが、is.nan()はNaNにのみTRUEを返します。


2-C-6

次の2つのコードの結果は同じですか?

x <- c(1, 2, 3)
y <- 1:3

結果は同じです。両方とも1 2 3というベクトルになります。

  • c(1, 2, 3): combine関数で明示的に結合
  • 1:3: コロン演算子で連続する整数を生成

ただし、内部的な型が微妙に異なることがあります(c(1, 2, 3)numeric1:3integer)。通常の使用では違いを意識する必要はありません。


2-C-7

次のコードを実行すると、どうなりますか?

x <- c(1, 2, 3)
y <- c(10, 20)
x + y

Rはベクトルをリサイクル(再利用)します。長さが異なるベクトル同士の演算では、短い方を繰り返して使います。

x + y
# 内部では c(1, 2, 3) + c(10, 20, 10) の計算
# 結果: 11 22 13

ただし、長いベクトルの長さが短いベクトルの整数倍でない場合、警告が出ます。意図しない挙動を避けるため、長さを揃えるのがベストプラクティスです。


2-C-8

matrix(1:6, ncol = 2, byrow = TRUE)を実行すると、どのような行列になりますか?

byrow = TRUEを指定すると、行(row)方向に要素が埋まります。

matrix(1:6, ncol = 2, byrow = TRUE)
#      [,1] [,2]
# [1,]    1    2
# [2,]    3    4
# [3,]    5    6

byrow = FALSE(デフォルト)の場合は列方向に埋まります:

matrix(1:6, ncol = 2)
#      [,1] [,2]
# [1,]    1    4
# [2,]    2    5
# [3,]    3    6

2-C-9

str()関数の主な役割は何ですか?

str()structure(構造) を表示する関数です。リストやデータフレームのような複雑なオブジェクトの中身を確認するときに便利です。

df <- data.frame(name = c("A", "B"), score = c(80, 90))
str(df)
# 'data.frame': 2 obs. of  2 variables:
#  $ name : chr  "A" "B"
#  $ score: num  80 90

RStudioのEnvironmentペインで変数をクリックしたときに表示される情報と同じものが、コンソールで確認できます。


2-C-10

データフレームと行列の主な違いは何ですか?

  • 行列(matrix): すべての要素が同じ型(すべて数値、またはすべて文字)
  • データフレーム(data.frame): 列ごとに異なる型を持てる(第1列は文字型、第2列は数値型など)

データ分析では、変数の型が異なることが普通なので、データフレームの方がよく使われます。

# データフレーム: 列ごとに型が異なる
df <- data.frame(
  name = c("太郎", "花子"),    # 文字型
  age = c(20, 22)               # 数値型
)

# 行列: すべて数値
mat <- matrix(c(20, 22, 170, 165), ncol = 2)

2-C-11

次のうち、オブジェクト名として使えないものはどれですか?

TRUEFALSEはRの予約語(特別な意味を持つ語)なので、オブジェクト名として使えません。

その他の予約語: - if, else, for, while, function - TRUE, FALSE, NULL, NA, NaN, Inf - break, next, repeat, return

また、数字で始まる名前(2data)も使えません。ピリオドで始まる名前(.hidden)は使えますが、Environmentペインで非表示になります。


2-C-12

class()typeof()の違いは何ですか?

  • class(): Rがオブジェクトをどう扱うか(高レベルの型)
  • typeof(): コンピュータ内部でどう保存されているか(低レベルの型)

例:

x <- 1:3
class(x)    # "integer" -- Rはこれを整数として扱う
typeof(x)   # "integer" -- 内部的にも整数

y <- factor(c("A", "B", "A"))
class(y)    # "factor" -- RはこれをFactor型として扱う
typeof(y)   # "integer" -- 内部的には整数で保存されている

通常はclass()を使えば十分です。typeof()は内部構造を詳しく調べたいときに使います。


ランクB: 実践スキルを磨こう

2-B-1

以下の3つの方法でベクトルを作成してください:

  1. c()を使って、1, 3, 5, 7, 9 のベクトルを作成
  2. seq()を使って、0から100まで10刻みのベクトルを作成
  3. rep()を使って、“A”を5回繰り返すベクトルを作成

それぞれの結果を確認してください。

  • c(): combine(結合)関数
  • seq(from = 開始, to = 終了, by = 刻み)
  • rep(x, times = 繰り返し回数)
# 1. c()を使った作成
vec1 <- c(1, 3, 5, 7, 9)
vec1

# 2. seq()を使った作成
vec2 <- seq(from = 0, to = 100, by = 10)
vec2

# 3. rep()を使った作成
vec3 <- rep("A", times = 5)
vec3

結果: - vec1: 1 3 5 7 9 - vec2: 0 10 20 30 ... 100(11個の要素) - vec3: "A" "A" "A" "A" "A"


2-B-2

次の名前付きリストを作成し、要素にアクセスしてください:

  • numbers: 1から5までのベクトル
  • words: “apple”, “banana”, “cherry” のベクトル
  • flag: TRUE

その後、以下を実行してください: - numbersの3番目の要素を取り出す - wordsの2番目の要素を取り出す

名前付きリストはlist(name1 = value1, name2 = value2, ...)で作成します。要素へのアクセスは$[[]]を使います。

# 名前付きリストの作成
my_list <- list(
  numbers = 1:5,
  words = c("apple", "banana", "cherry"),
  flag = TRUE
)

# 構造を確認
str(my_list)

# numbersの3番目の要素
my_list$numbers[3]
# または
my_list[[1]][3]

# wordsの2番目の要素
my_list$words[2]
# または
my_list[[2]][2]

結果: - my_list$numbers[3]: 3 - my_list$words[2]: "banana"


2-B-3

次のデータフレームを作成してください:

name age score
太郎 20 85
花子 22 90
次郎 21 78

その後、passという列を追加してください(score >= 80ならTRUE、そうでなければFALSE)。

  • data.frame(列名1 = ベクトル1, 列名2 = ベクトル2, ...)で作成
  • 列の追加はdf$新しい列名 <- ベクトル
  • 条件判定はdf$score >= 80
# データフレームの作成
df <- data.frame(
  name = c("太郎", "花子", "次郎"),
  age = c(20, 22, 21),
  score = c(85, 90, 78)
)

# 内容を確認
df

# pass列を追加
df$pass <- df$score >= 80

# 結果を確認
df

結果:

  name age score  pass
1 太郎  20    85  TRUE
2 花子  22    90  TRUE
3 次郎  21    78 FALSE

2-B-4

2-B-3で作成したデータフレームのname列をFactor型に変換してください。その後、levels()関数で水準を確認してください。

  • as.factor()関数で文字型をFactor型に変換
  • levels()関数で水準(ユニークな値)を確認
# name列をFactor型に変換
df$name <- as.factor(df$name)

# 型を確認
class(df$name)

# 水準を確認
levels(df$name)

# 構造を確認
str(df)

結果: - class(df$name): "factor" - levels(df$name): "太郎" "花子" "次郎"

Factor型に変換すると、str(df)の出力で$ name: Factor w/ 3 levels ...と表示されます。


2-B-5

次の行列を作成し、指定された要素を取り出してください:

# 1から12までの数値で、3行4列の行列を作成(列方向に埋める)
mat <- matrix(1:12, nrow = 3)

以下を取り出してください: - 2行3列の要素 - 1行目全体 - 3列目全体

  • 行列の要素アクセス: mat[行番号, 列番号]
  • 行全体: mat[行番号, ]
  • 列全体: mat[, 列番号]
# 行列の作成
mat <- matrix(1:12, nrow = 3)
mat

# 2行3列の要素
mat[2, 3]

# 1行目全体
mat[1, ]

# 3列目全体
mat[, 3]

結果:

行列:
     [,1] [,2] [,3] [,4]
[1,]    1    4    7   10
[2,]    2    5    8   11
[3,]    3    6    9   12

mat[2, 3]:  8
mat[1, ]:   1 4 7 10
mat[, 3]:   7 8 9

ランクA: AI協働に挑戦しよう

2-A-1

課題: 次のような入れ子になった複雑なリスト構造があります。

complex_list <- list(
  group1 = list(
    data = data.frame(x = 1:3, y = 4:6),
    info = "Group 1 data"
  ),
  group2 = list(
    data = data.frame(x = 7:9, y = 10:12),
    info = "Group 2 data"
  )
)

このリストから「group2datay列の2番目の要素」を取り出したいのですが、どうすればよいでしょうか?

AIに相談しながら、正しいアクセス方法を見つけてください。また、複数の方法がある場合は、それぞれ試してみてください。

提出物: AIとの対話ログ、試したコード、最終的な答え(11が出力されればOK)。


2-A-2

課題: あなたが実施したアンケートやテストの結果データを想定してください(実際のデータがなければ、架空のデータでOK)。

例: - 回答者ID、年齢、性別、質問1〜5の回答(5段階評価)

このデータをRのデータフレームとして作成するとき、各列の型(数値型、文字型、Factor型など)をどう設定すべきか、AIに相談してください。

考えるポイント: - どの列を数値型にすべきか? - どの列をFactor型にすべきか? - 欠測値がある場合、どう扱うか?

提出物: - AIとの対話内容 - 設計したデータフレームのコード - str()の出力結果 - なぜその型を選んだかの説明


まとめ

このユニットでは、Rの基本的なデータ型とオブジェクトについて学びました:

  • ベクトル: 同じ型の要素の集まり(c(), seq(), rep()
  • リスト: 異なる型の要素を保持できる([[]], $でアクセス)
  • データフレーム: 列ごとに異なる型を持てる表形式データ
  • Factor型: カテゴリカルデータの分析に必須

データ型を正しく理解し、使い分けることで、データ分析がスムーズに進みます。次のユニット U4. 基本的なデータ操作では、これらのオブジェクトを使った演算やインデキシングについて学びます。


進捗: あなたは今 2-C-12 まで完了しました!(と仮定)次は 2-B-1 に進みましょう。