Rのデータ型:6つの基本データ型と型変換
前回のレッスンでは、代入と出力について学びました。Rプログラム内のすべてのデータ(数値、文字列、ブール値)には、それぞれ固有の「型」があります。このレッスンでは、Rの6つの基本データ型について詳しく解説し、Rを用いたデータサイエンスに欠かせないスキルである「型変換」を習得します。
Rは動的型付け言語ですが、だからといって型が重要ではないというわけではありません。Rのエラーの90%は型変換に関連しています。
1. 学習内容
- Rの6つの基本データ型(数値型、整数型、文字列型、論理型、複素数型、生データ型)
typeof()とclass()の違いis.*型チェック関数のファミリーas.*型変換関数のファミリー- 4つの特殊な値(NA、NaN、Inf、NULL)の違い
- 実世界のアプリケーションにおける一般的な型変換のシナリオ
2. 「一見平等に見える」という罠
コードを書く前に、多くの初心者を困惑させる例を見てみましょう:
# These two numbers look the same, but R considers them "unequal"
1 == 1L
# [1] FALSE
# Verify their types
typeof(1)
# [1] "double" (Double-precision floating-point numbers)
typeof(1L)
# [1] "integer" (Integer)
これは直感に反しませんか? Rでは、「1」と「1L」は同じものではありません。このレッスンでは、Rのデータ型の秘密をすべて解き明かしていきます。
3. Rの6つの基本データ型
R におけるすべてのデータは、以下の 6 つの基本型のいずれかに属します:
graph TB
A[R Data Types]
A --> B[numeric<br/>Double-precision floating-point numbers<br/>Default number]
A --> C[integer<br/>Integer<br/>Need to add L Suffix]
A --> D[character<br/>String<br/>Quotation marks must be used]
A --> E[logical<br/>Logical value<br/>TRUE/FALSE]
A --> F[complex<br/>Plural<br/>1+2i]
A --> G[raw<br/>Byte<br/>as.raw 0xff]
style A fill:#fff3cd
style B fill:#cce5ff
style C fill:#cce5ff
style D fill:#d4edda
style E fill:#f8d7da
style F fill:#e1d4ff
style G fill:#ffe1e1
(1) 6種類の概要表
| 型 | 意味 | 例 | typeof() の戻り値 |
|---|---|---|---|
| 数値 | 倍精度浮動小数点数(デフォルト) | 3.14, -2.5, 1e3 |
"double" |
| 整数 | 整数(末尾に L を付けること) |
1L, 100L, -5L |
"integer" |
| 文字 | 文字列(引用符で囲む必要があります) | "Hello", 'R' |
"character" |
| 論理 | 論理値(ブール値) | TRUE, FALSE |
"logical" |
| 複合語 | 複数形 | 1+2i, 3-4i |
"complex" |
| raw | バイト型 | as.raw(0xff) |
"raw" |
(2) 各タイプの詳細な説明
# numeric —— Double-precision floating-point numbers(Default number)
x <- 3.14
typeof(x)
# [1] "double"
# integer -- Strict Integers (Add L Suffix)
x <- 10L
typeof(x)
# [1] "integer"
# character —— String
x <- "Hello R"
typeof(x)
# [1] "character"
# logical —— Logical value(Must be all uppercase)
x <- TRUE
typeof(x)
# [1] "logical"
# complex —— Plural
x <- 1 + 2i
typeof(x)
# [1] "complex"
TRUE を true や True と記述することはできません。そうすると、object 'true' not found というエラーが発生します。
(3) 整数と浮動小数点数:どちらをいつ使うべきか?
| シナリオ | 推奨タイプ | 理由 |
|---|---|---|
| 一般的な数学的計算 | 数値計算 | Rのデフォルト設定;これについては気にする必要はありません |
| 大規模な数値配列(10億要素以上) | 整数 | メモリ使用量を半分に削減 |
| ビット演算、ID、カウント | 整数 | 意味的に曖昧さがない |
浮動小数点比較の結果、sqrt() など |
数値 | 数学演算は本質的に浮動小数点演算である |
# Performance Comparison(1 A billion integers vs 1 A billion floating-point numbers)
# integer: ~400 MB
# numeric: ~800 MB
# Not required in normal situations integer,numeric That's enough
integer タイプはまったく必要ありません。大規模な計算(10億要素以上)を行う場合を除き、numeric で十分です。
4. typeof() 対 class():混同されがちな2つの関数
Rには「型」を確認できる関数が2つありますが、それらは意味が異なります。
(1) 違いをひと目でわかるガイド
graph TB
A["R Object"] --> B["typeof()<br/>Bottom Layer C Type<br/>6 Basic Types"]
A --> C["class()<br/>Business OOP Class<br/>data.frame / Date / factor"]
B --> D["double / integer<br/>character / logical<br/>complex / raw"]
C --> E["Business Concepts<br/>(20+ kinds)"]
style A fill:#fff3cd
style B fill:#cce5ff
style C fill:#d4edda
(2) 実際の比較
# 1. Ordinary Vectors:The two are consistent
x <- 1:10
typeof(x)
# [1] "integer"
class(x)
# [1] "integer"
# 2. Data Frame: The two are different!
y <- data.frame(a = 1:3, b = c("x", "y", "z"))
typeof(y)
# [1] "list" ← The bottom layer is list
class(y)
# [1] "data.frame" ← In business terms, it's a data frame.
(3) 選定に関する推奨事項
| シナリオ | どちらを使うか |
|---|---|
| 「Rの中でこれが何なのか」を知りたい | typeof() |
| 「これがビジネスにどのような意味を持つのか」を知りたい | class() |
| 初心者 | おすすめ class()(より直感的) |
5. 型チェック:is.* 関数群
R には型チェック用の is.* 関数群が用意されており、すべての関数は TRUE または FALSE を返す。
(1) 一般的なチェック関数
| チェック機能 | 目的 | 結果例 |
|---|---|---|
is.numeric(x) |
数値(数値または整数)か | is.numeric(1L) → TRUE |
is.integer(x) |
厳密な整数(末尾に「L」が付く) | is.integer(1) → FALSE |
is.character(x) |
文字列か | is.character("a") → TRUE |
is.logical(x) |
は論理値である | is.logical(TRUE) → TRUE |
is.na(x) |
欠損値は NA | is.na(NA) → TRUE |
is.null(x) |
NULL(空値) | is.null(NULL) → TRUE |
(2) 主な落とし穴:is.numeric() は整数と倍精度浮動小数点数を区別しない
# is.numeric() is the "superset" of is.integer()
is.numeric(1) # [1] TRUE
is.numeric(1L) # [1] TRUE
is.integer(1) # [1] FALSE
is.integer(1L) # [1] TRUE
is.numeric() を使用し、厳密な整数かどうかを確認するには is.integer() を使用します。
6. 型変換:as.* 関数群
Rのas.*関数群は、ある型を別の型に強制変換することができます。
(1) 一般的な変換関数
| 変換関数 | 目的 | 失敗時の挙動 |
|---|---|---|
as.numeric(x) |
→ 番号 | NAを返す + 警告 |
as.integer(x) |
→ 整数 | 小数切り捨て |
as.character(x) |
→ 文字列 | 常に成功 |
as.logical(x) |
→ 論理値 | 0 → FALSE、その他の数値 → TRUE |
(2) コンバージョン失敗によるコスト
# String → Numbers(Success)
as.numeric("3.14")
# [1] 3.14
# String → Numbers(Failure)
as.numeric("Hello")
# Warning: NAs introduced by coercion
# [1] NA
NAの数を必ず確認してください:
# One failure won't stop me,But there will be a warning
as.numeric(c("1", "2", "abc", "4"))
# Warning: NAs introduced by coercion
# [1] 1 2 NA 4
(3) 実際のシナリオ:CSVファイルの読み込み後の型不一致
CSVファイルを読み込む際によくある落とし穴の一つは、数値の列が文字として解釈されてしまうことです:
# Suppose we read one CSV,All columns are character
df <- data.frame(
id = c("1", "2", "3"),
value = c("10.5", "20.3", "30.1")
)
# Before Conversion
str(df)
# 'data.frame': 3 obs. of 2 variables:
# $ id : chr "1" "2" "3"
# $ value: chr "10.5" "20.3" "30.1"
# After conversion
df$id <- as.numeric(df$id)
df$value <- as.numeric(df$value)
str(df)
# $ id : num 1 2 3
# $ value: num 10.5 20.3 30.1
readr::read_csv()について学ぶ際、型が自動的に推論されます。これはread.csv()よりもはるかに賢いため、この問題は発生しません。
- 特殊な値:NA / NaN / Inf / NULL
Rには、まったく異なる意味を持つ4つの特殊な値があり、これが初心者にとって最大の落とし穴となっています。
(1) 4つの特別な値の関係
graph TB
A["Missing values/Null value"]
A --> B[NA<br/>Missing values Not Available<br/>Missing Data,Not assigned,Conversion Failed]
A --> C[NaN<br/>Non-numeric Not a Number<br/>Not defined mathematically]
A --> D[Inf<br/>Infinity Infinity<br/>1/0,exp 1000]
A --> E[NULL<br/>Empty object<br/>Undefined,Functions with no return value]
B --> F[Includes NaN]
style A fill:#fff3cd
style B fill:#d4edda
style C fill:#f8d7da
style D fill:#cce5ff
style E fill:#e1d4ff
(2) 4つの特殊値の比較表
| 特別な値 | typeof | 意味 | 使用例 | 確認方法 |
|---|---|---|---|---|
| NA | 論理値 | 欠損値 | データ欠損、未割り当て、変換失敗 | is.na() |
| 数値ではない | ダブル | 非数値 | 0/0,sqrt(-1) |
is.nan() |
| Inf | double | 正の無限大 | 1/0, exp(1000) |
is.infinite() |
| NULL | NULL | 空のオブジェクト | 未定義、関数が値を返さない | is.null() |
(3) NA:「欠損データ」の中で最も一般的なタイプ
# NA Participating in calculations is contagious(NA It won't disappear)
x <- c(1, 2, NA, 4)
sum(x)
# [1] NA <- The entire result turned out NA
# Must use na.rm = TRUE Skip NA
sum(x, na.rm = TRUE)
# [1] 7
# Inspection NA Location
is.na(x)
# [1] FALSE FALSE TRUE FALSE
(4) NaN:数学における「未定義」
# 0 Divide by 0
0 / 0
# [1] NaN
# Taking the square root of a negative number
sqrt(-1)
# Warning: NaNs produced
# [1] NaN
# NaN It is special. NA(NA a subset of)
is.na(NaN)
# [1] TRUE ← NaN Me too NA
(5) 解説:数学における「無限」
# 1 Divide by 0
1 / 0
# [1] Inf
# A negative number divided by 0
-1 / 0
# [1] -Inf
# Inspection Inf
is.infinite(c(1, Inf, -Inf, 2))
# [1] FALSE TRUE TRUE FALSE
(6) NULL:空のオブジェクト(あるいは存在すらしないオブジェクト)
# NULL Doesn't take up memory
x <- NULL
length(x)
# [1] 0
# NA occupies 1 position, NULL disappears entirely
length(c(1, 2, NA, 4)) # [1] 4
length(c(1, 2, NULL, 4)) # [1] 3 ← NULL Swallowed whole
# Default return value for functions with no return value NULL
my_void_func <- function() { }
result <- my_void_func()
is.null(result)
# [1] TRUE
NA と NULL の根本的な違いは、NA は「その位置は存在するが値が不明」を意味するのに対し、NULL は「その位置がまったく存在しない」を意味する点です。前者は欠損データを示すためによく使用され、後者は関数が戻り値を持たない場合に使用されることがよくあります。
8. 完全な例:型変換の総合演習
以下は、このレッスンで取り上げたすべての概念を結びつけた完全なワークフローの例です。
▶ サンプル:ユーザー入力データのクリーニング
# ============================================
# Cleaning User-Input Data
# Features:Convert a character vector to a number,Processing NA
# ============================================
# 1. Simulate from CSV Read"Dirty Data"(All of them character)
raw_data <- c("1", "2.5", "3.14", "abc", "5", "", "7.8")
cat("Raw Data:\n")
print(raw_data)
cat("Primitive Types:", typeof(raw_data), "\n\n")
# 2. Convert to a number ("abc" and "" will become NA)
nums <- as.numeric(raw_data)
cat("After conversion:\n")
print(nums)
# 3. See which ones are NA
na_positions <- is.na(nums)
cat("\nNA Location:")
print(na_positions)
# 4. Statistics NA Quantity
na_count <- sum(na_positions)
cat("\nNA Quantity:", na_count, "\n")
# 5. Keep only non- NA the number
clean_nums <- nums[!na_positions]
cat("\nData After Cleaning:")
print(clean_nums)
# 6. Statistical Indicators
cat("\n=== Statistical Indicators ===\n")
cat("Total Number of Elements:", length(raw_data), "\n")
cat("Valid Data:", length(clean_nums), "\n")
cat("Invalid data:", na_count, "\n")
cat("Total:", sum(clean_nums), "\n")
cat("Average:", round(mean(clean_nums), 2), "\n")
cat("Maximum value:", max(clean_nums), "\n")
cat("Minimum value:", min(clean_nums), "\n")
期待される出力(抜粋):
Raw Data:
[1] "1" "2.5" "3.14" "abc" "5" "" "7.8"
Primitive Types: character
After conversion:
[1] 1.00 2.50 3.14 NA 5.00 NA 7.80
NA Location:
[1] FALSE FALSE FALSE TRUE FALSE TRUE FALSE
NA Quantity: 2
Data After Cleaning:
[1] 1.00 2.50 3.14 5.00 7.80
=== Statistical Indicators ===
Total Number of Elements: 7
Valid Data: 5
Invalid data: 2
Total: 19.44
Average: 3.89
Maximum value: 7.8
Minimum value: 1
(1) 手順
| ステップ | 操作 | 説明 |
|---|---|---|
| 1 | RStudioプロジェクトの作成 r-types |
File → New Project |
| 2 | 新しいスクリプト data_cleaning.R を作成 |
上記のコードをコピー |
| 3 | すべて選択 → Ctrl+Enter |
コンソールに送信 |
| 4 | 出力を確認する | 「NA」というラベルと、クリーニング後の結果を確認する |
❓ よくある質問
typeof() と class()、どちらを使うべきですか?typeof()(6つの基本型)を、ビジネス関連の型について知りたい場合は class()(data.frame/Date/factor)を使用してください。初心者の方には、class()の方が直感的に理解しやすいでしょう。is.numeric(1L) は TRUE を返すのに、is.integer(1L) も TRUE を返すのですか?is.numeric() は is.numeric() の「親集合」だからです。整数は常に数値ですが、その逆は成り立ちません。推奨:値が「数値」であるかどうかを確認するには is.numeric() を使用し、値が「厳密な整数」であるかどうかを確認するには is.integer() を使用してください。NULL と NA のどちらを選べばよいですか?NA を、 「オブジェクトが存在しない」(場所すら存在しない)を示す場合は NULL を使用してください。NAは、データ処理のシナリオの大部分で使用されます。📖 まとめ
- Rの6つの基本データ型:数値(デフォルト)、整数(末尾に
Lが付く)、文字(文字列)、論理(ブール値)、複素数(複素数)、生データ(バイト) typeof()では低レベルの C データ型(6 つの基本型)を扱います;class()ではビジネス関連のデータ型(data.frame、Date、factor)を扱います — 初心者の方にはclass()の方が直感的に理解しやすいでしょうis.*関数群は型をチェックします(TRUE/FALSEを返します)。as.*関数群は型変換を行います(変換に失敗した場合はNAを返し、警告を出力します)。as.numeric()整数とdouble型の両方に一致します。as.integer()を使用すると、両者を厳密に区別します。- 4つの特殊な値にはそれぞれ異なる意味があります:NA(欠損値—感染)、NaN(数値ではない)、Inf(無限大)、およびNULL(空のオブジェクト—存在しない)
- NAの処理に関する標準的な方法:
sum(x, na.rm = TRUE)NAをスキップする;!is.na(x)NAを除外する
📝 練習問題
-
基本演習:6つの基本データ型(数値、整数、文字、論理、複素数、生データ)を表す6つの変数を定義してください。
typeof()を使用して各変数の型を確認し、6つのtypeof()コマンドの出力のスクリーンショットを保存してください。 -
基本問題:
as.numeric()を使用して文字ベクトルc("1", "2.5", "3.14", "abc", "5")を数値に変換し、警告メッセージと変換結果をログに出力し、is.na()を使用してどの要素が NA になったかを確認してください。コンソールの出力をスクリーンショットに撮り、保存してください。 -
基本演習:RStudioのコンソールで、
0/0、1/0、-1/0、およびsqrt(-1)を計算し、それぞれの結果を記録した上で、is.na()、is.nan()、およびis.infinite()を用いて、各値がどの特殊値に属するかを検証してください。 -
応用問題:ベクトル
scores <- c(85, 92, NA, 78, NA, 95, 88)を定義してください。要件:① 合計スコアを計算してください(NAを除く)。② 平均スコアを計算してください(NAを除き、小数点以下2桁に四捨五入)。③!is.na()を使用して、NAではない要素をフィルタリングしてください。④ NAの個数を数えてください。各ステップの出力のスクリーンショットを保存してください。 -
課題:「CSVファイルの読み込み後の型不一致」をシミュレートするRスクリプトを作成してください:① すべての列の型が
characterになるように、手動で data.frame を構築します; ②as.numeric()を使用して、列の 1 つを数値型に一括変換する; ③sum(is.na(df$col))を使用して、変換に失敗した要素の数をカウントする; ④paste()を使用して警告メッセージを作成し、出力する。スクリプトの実行後、スクリーンショットを撮影し、コンソールの出力全体を保存してください。



