Rの演算子:算術演算、比較演算、論理演算の完全ガイド
前回のレッスンでは、ベクトルとデータ型について学びました。今回のレッスンでは、Rプログラミングの「基礎」である演算子について詳しく見ていきます。単純な計算から複雑な統計モデルに至るまで、すべてのRプログラムは、その根幹において演算子によって支えられています。
Rの演算子のセットは他の言語のものとほぼ同じですが、R特有の2つの細かい点があります。それは、整数除算 %% %/% と、ベクトル化された「ブロードキャスティング」の挙動です。このレッスンでは、すべての演算子について詳しく解説します。
1. 学習内容
- 算術演算子の4つの主要なカテゴリ(基本演算+整数除算+ベクトル演算)
- 比較演算子の3つの種類(数値比較+文字列比較+特殊な値)
- 3種類の論理演算子(AND、OR、NOT + 短絡評価)
- 5つの独自のR演算子 (
%in%%*%%/%%%:) - 演算子の優先順位(曖昧な式を避ける)
- 実世界でのアプリケーションにおける一般的な計算上の落とし穴
2. ある金銭計算をめぐる物語
(1) 課題:手作業による利益の計算
ボブは会計士で、月末になると上司のために「支店売上報告書」を作成しなければなりません:
同社には5つの支店があり、今月の各支店の売上高は
120, 150, 80, 200, 175万元です。次の計算を行ってください:
- 総売上高、平均売上高
- 店舗あたりの利益(売上高 × 30% の利益率)
- どの店舗の売上が平均を上回っているか(特に注意が必要)
- 総利益の整数部分(10,000元単位、切り捨て)
電卓を使って手計算すると5分かかります。Excelを使う場合は、スプレッドシートを作成して数式を入力する必要があります。Rを使う場合は――
(2) Rを用いた解決策
# 5 Sales at each branch(10,000 yuan)
sales <- c(120, 150, 80, 200, 175)
# All calculations are completed with a single line of code
total_sales <- sum(sales) # Total Sales 725
avg_sales <- mean(sales) # Average 145
profit <- sales * 0.3 # Profit Vector
high_sales <- sales[sales > avg_sales] # Branches with Above-Average Performance
profit_int <- profit %/% 1 # Integer Profit(Integer Division)
cat("Total Sales:", total_sales, "10,000 yuan\n")
cat("Average Sales:", avg_sales, "10,000 yuan\n")
cat("Total Profit(Integer):", sum(profit_int), "10,000 yuan\n")
cat("Above-average sales at branch locations:", high_sales, "\n")
10行のコードで5つの計算タスクを解決。これこそがRの演算子の力です――1行のコードが、一連の演算のベクトルに相当するのです。
3. 算術演算子:数学的な計算
(1) 基本的な算術演算子
| 演算子 | 意味 | 例 | 結果 |
|---|---|---|---|
+ |
追加 | 2 + 3 |
5 |
- |
減少 | 5 - 2 |
3 |
* |
乗算 | 4 * 3 |
12 |
/ |
削除 | 7 / 2 |
3.5 |
^ または ** |
電力 | 2 ^ 3 |
8 |
%% |
引き算(余り) | 7 %% 2 |
1 |
%/% |
整数の除算 | 7 %/% 2 |
3 |
(2) 整数の除算:R固有
# 7 / 2 = 3.5(Ordinary Division)
7 / 2
# [1] 3.5
# 7 %/% 2 = 3(Integer Division,Round down)
7 %/% 2
# [1] 3
# 7 %% 2 = 1 (Modulo, Remainder)
7 %% 2
# [1] 1
# Practical Application: Convert seconds to "hr:min:s"
total_seconds <- 3725
hours <- total_seconds %/% 3600
minutes <- (total_seconds %% 3600) %/% 60
seconds <- total_seconds %% 60
cat(hours, "hr", minutes, "min", seconds, "s\n")
# 1 hr 2 min 5 s
%% と %/% は、データ処理において非常に一般的です。具体的には、ページネーション (page %/% page_size)、グループ化 (id %% 10—末尾の数字に基づいて10のグループに分割すること)、および時刻変換などが挙げられます。
(3) ベクトルの演算(重要ポイント)
Rにおける算術演算はデフォルトでベクトル化される。これはRの最大の強みのひとつである:
graph LR
A["x = 1, 2, 3"] --> C["+ 10"]
C --> D["11, 12, 13"]
E["x = 1, 2, 3"] --> F["+ y = 10, 20, 30"]
F --> G["11, 22, 33"]
style A fill:#cce5ff
style C fill:#d4edda
style D fill:#d4edda
# Vector + Scalar(Scalar"Broadcast"Go to each element)
c(1, 2, 3) + 10
# [1] 11 12 13
# Vector + Vector(Element-wise Operations)
c(1, 2, 3) + c(10, 20, 30)
# [1] 11 22 33
# When the lengths are different,"Loop"
c(1, 2, 3, 4) + c(10, 20)
# Warning: longer object length is not a multiple of shorter object length
# [1] 11 22 13 24
(4) 一般的な数学関数
| 機能 | 目的 | 例 |
|---|---|---|
abs() |
絶対値 | abs(-5) → 5 |
sqrt() |
平方根 | sqrt(16) → 4 |
| 自然対数 | → | |
log10() |
常用対数 | log10(1000) → 3 |
log2() |
ベース2 | log2(8) → 3 |
exp() |
xのe乗 | exp(1) → 2.718 |
| まとめ | round() |
|
floor() |
切り捨て | floor(3.7) → 3 |
| まとめ | ceiling() |
ceiling(3.2) → 4 |
4. 比較演算子:真偽値の判定
(1) 6 比較演算子
| 演算子 | 意味 | 例 | 結果 |
|---|---|---|---|
== |
= | 5 == 5 |
TRUE |
!= |
異なる | 5 != 3 |
TRUE |
< |
より小さい | 3 < 5 |
TRUE |
> |
より大きい | 5 > 3 |
TRUE |
<= |
以下 | 5 <= 5 |
TRUE |
>= |
以上 | 5 >= 6 |
FALSE |
(2) ⚠️ 重要な落とし穴:等号1つと等号2つの違い
# Single = It is an assignment
x = 5
# Double equal sign == It is a comparison
x == 5
# [1] TRUE
== を使用してください。= を使用しないでください。R は「=`」エラーを報告しませんが(これは有効な代入であるため)、結果は完全に間違ったものになります。
(3) 文字列の比較(辞書順)
# Character by ASCII Code Comparison
"apple" < "banana"
# [1] TRUE ← 'a' Coding < 'b'
# Numeric characters cannot be compared directly for size.(Character-by-character comparison,Not by value)
"9" > "10"
# [1] TRUE <- '9' (0x39) > '1' (0x31), Not a numerical comparison!
# The Correct Way to Do It:Convert to a number
as.numeric("9") > as.numeric("10")
# [1] FALSE
(4) 特殊値の比較
# NA The results of the comparison are NA(No TRUE/FALSE)
NA == 5
# [1] NA
# Decision NA Must use is.na()
is.na(NA)
# [1] TRUE
# NaN Comparison of
NaN == NaN
# [1] NA <- NaN == NaN is also NA!
is.na() を使用してください。
5. 論理演算子:条件の組み合わせ
(1) 3つの基本的な論理演算子
| 演算子 | 意味 | 例 | 結果 |
|---|---|---|---|
& |
要素ごとのAND | TRUE & FALSE |
FALSE |
| |
要素ごとのOR | TRUE | FALSE |
TRUE |
! |
キャンセル | !TRUE |
FALSE |
(2) ベクトル化(要点)
x <- c(TRUE, TRUE, FALSE, FALSE)
y <- c(TRUE, FALSE, TRUE, FALSE)
# Elemental Level AND(Vectorization)
x & y
# [1] TRUE FALSE FALSE FALSE
# Elemental Level OR
x | y
# [1] TRUE TRUE TRUE FALSE
(3) 短絡評価:&& および ||
| 演算子 | 動作 | 目的 |
|---|---|---|
& |
要素ごとのAND、すべての計算 | ベクトル論理演算 |
&& |
短絡AND、最初のものだけが有効 | if条件 |
| |
要素ごとのOR、すべての計算 | ベクトル論理演算 |
|| |
短絡OR、最初のものだけが有効 | if条件 |
# if Used in the conditions &&(Check only the first element)
if (x > 0 && x < 10) {
cat("x is between 0-10\n")
}
# Used in vector logic &(Check all elements)
c(1, 2, 11) > 0 & c(1, 2, 11) < 10
# [1] TRUE TRUE FALSE
if の条件では、&& および || を使用する必要があります。& や | は使用しないでください。そうしないと、予期しない結果になる可能性があります。
(4) 実践編:複合条件によるフィルタリング
# Find 18-30 Adults aged
ages <- c(15, 22, 28, 35, 40, 19)
adults <- ages[ages >= 18 & ages <= 30]
adults
# [1] 22 28 19
# Identify the failing or perfect scores
scores <- c(58, 60, 75, 100, 45, 90)
special <- scores[scores < 60 | scores == 100]
special
# [1] 58 100 45
6. R固有の演算子
(1) 5人の特殊部隊員
| 演算子 | 意味 | 例 | 結果 |
|---|---|---|---|
%in% |
所属先(メンバー確認) | 3 %in% c(1,2,3) |
TRUE |
%*% |
行列の乗算 | matrix(1:4,2) %*% matrix(1:4,2) |
行列 |
%/% |
整数の除算 | 7 %/% 2 |
3 |
%% |
離型 | 7 %% 2 |
1 |
: |
シーケンス | 1:5 |
1 2 3 4 5 |
(2) %in% の詳細な説明
%in% は、データフィルタリングの「中核」となる演算子です:
# Is the element in the vector?
c(1, 2, 3) %in% c(2, 4, 6)
# [1] FALSE TRUE FALSE <- 1, 3 Not here; 2 is
# Practical Application: Filter "Beijing, Shanghai, and Guangzhou" City
cities <- c("Beijing", "Shanghai", "Shenzhen", "Guangzhou", "Hangzhou")
target <- c("Beijing", "Shanghai", "Guangzhou")
cities[cities %in% target]
# [1] "Beijing" "Shanghai" "Guangzhou"
(3) 行列の乗算入門 %*%
# Basic Multiplication(Elemental Level)
matrix(1:4, 2, 2) * matrix(1:4, 2, 2)
# [,1] [,2]
# [1,] 1 9
# [2,] 4 16
# Matrix Multiplication(Linear Algebra)
matrix(1:4, 2, 2) %*% matrix(1:4, 2, 2)
# [,1] [,2]
# [1,] 7 15
# [2,] 10 22
7. 演算子の優先順位(曖昧さを避ける)
Rの演算子には特定の優先順位があります。迷ったときは括弧を使うのが最も安全な方法です:
| 優先度 | 演算子 | 説明 |
|---|---|---|
| 高 | ^ |
電源操作 |
| ↑ | * / |
掛け算と割り算 |
| ↑ | + - |
足し算と引き算 |
| ↑ | < <= > >= == != |
比較 |
| ↑ | ! |
取り消し |
| ↑ | & && |
With |
| または | ||
| 低 | <- |
課題 |
# Without parentheses(By priority)
1 + 2 * 3
# [1] 7 <- 2*3=6, then +1
# Add parentheses(Clarify Intent)
(1 + 2) * 3
# [1] 9
# Be sure to use parentheses in complex expressions.
# Find 18-65 yrs
ages <- c(15, 25, 70, 30)
adults <- ages[ages >= 18 & ages <= 65] # ✅ Adding parentheses makes it clearer
8. 完全な例:支店売上高の包括的な分析
以下は、このレッスンで学んだすべての演算子を組み合わせた完全なワークフローの例です。
▶ サンプル:支店の売上に関する包括的な分析
# ============================================
# Comprehensive Analysis of Branch Sales
# Features:Analysis Using Various Operators 5 Sales Data by Branch
# ============================================
# 1. Prepare data
sales <- c(Beijing = 120, Shanghai = 150, Shenzhen = 80, Guangzhou = 200, Hangzhou = 175)
cat("Raw Sales Data(10,000 yuan):\n")
print(sales)
# 2. Arithmetic Operations:Total Sales,Average,Highest,Lowest
total <- sum(sales) # Sum
avg <- mean(sales) # Average
cat("\nTotal Sales:", total, "10,000 yuan\n")
cat("Average Sales:", avg, "10,000 yuan\n")
cat("Top Sales:", max(sales), "10,000 yuan\n")
cat("Minimum Sales:", min(sales), "10,000 yuan\n")
# 3. Arithmetic Operations:Profit(30% Profit Margin)
profit_rate <- 0.3
profit <- sales * profit_rate # Vector × Scalar
cat("\nTotal Profit:", sum(profit), "10,000 yuan\n")
# 4. Comparison + Logic:Identify branches that perform above average
is_above_avg <- sales > avg # Comparison:Which ones are above average?
cat("\nBranches with Above-Average Performance:")
print(sales[is_above_avg])
# 5. Comparison + Logic:Identify low-performing stores(< 1,000,000)
is_low <- sales < 100
cat("\nLow-Sales Stores(< 1,000,000):")
print(sales[is_low])
# 6. Integer Operations:Round Profit to the Nearest Whole Number + Grouping
profit_int <- profit %/% 1 # Integer Division(Round down)
cat("\nRound Profit to the Nearest Whole Number:")
print(profit_int)
# 7. %in% Filter
target_cities <- c("Beijing", "Shanghai", "Guangzhou")
selected <- sales[names(sales) %in% target_cities]
cat("\nSales in Target Cities:")
print(selected)
期待される出力(抜粋):
Raw Sales Data(10,000 yuan):
Beijing Shanghai Shenzhen Guangzhou Hangzhou
120 150 80 200 175
Total Sales: 725 10,000 yuan
Average Sales: 145 10,000 yuan
Top Sales: 200 10,000 yuan
Minimum Sales: 80 10,000 yuan
Branches with Above-Average Performance:
Guangzhou Hangzhou
200 175
Total Profit: 217.5 10,000 yuan
Low-Sales Stores(< 1,000,000):
Shenzhen
80
❓ よくある質問
%% と %/% の違いは何ですか?%% は剰余演算(余りを返す)を行い、%/% は整数除算(商を返す)を行います。例えば、7 %/% 2 = 3(商)と7 %% 2 = 1(余り)などです。これらは、ページネーション、時間変換、グループ化などの場面で非常に頻繁に使用されます。& と &&、どちらを使うべきですか?& を、if 条件(ショートサーキット評価、最初の要素のみが評価される)には && を使用してください。Rは他の言語ほど厳密にこれらを区別しませんが、間違ったものを使用すると、if文の動作が不正になる可能性があります。📖 まとめ
- 演算子の4つの主要なカテゴリ:算術演算子 (
+ - * / ^ %% %/%)、比較演算子 (== != < > <= >=)、論理演算子 (& \| !)、代入演算子 (<- = -> <<-) - Rの機能:整数除算
%%%/%、ベクトル化された「ブロードキャスト」動作、%in%メンバーチェック - ベクトル + スカラー = スカラーが各要素にブロードキャストされる;ベクトル + ベクトル = 要素ごとの演算
- 文字列は、数値そのものではなく、ASCIIエンコーディングに基づいて比較されます。数値文字は、
as.numeric()を使用して変換する必要があります。 if:条件付き演算用&&\|\|(短絡評価)、および&\|:ベクトル論理用(ベクトル化)- 演算子の優先順位に注意してください。迷った場合は、括弧を使ってください(可読性を簡潔さよりも優先しましょう)
NA == 5結果はNAとなります(TRUE/FALSE ではありません)。これを評価するにはis.na()を使用してください
📝 練習問題
-
基本問題:R を使用して、3つの異なる方法(①
sum(1:100)、② ループ、③ 数式n(n+1)/2)で 1+2+3+...+100 を計算してください。3つの方法すべてで結果が一致することを確認してください。 -
基本演習:秒数
total_seconds <- 3725を「時間:分:秒」の形式に変換し(このレッスンの整数除算の例を参照)、コードと出力のスクリーンショットを保存してください。 -
基本問題:
%in%を使用して、ベクトルc(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)内の偶数を(c(2, 4, 6, 8, 10) %in%で説明した方法を用いて)探し出し、その出力のスクリーンショットを撮ってください。 -
応用問題:比較演算子および論理演算子を用いて、5人の生徒
scores <- c(85, 92, 78, 95, 88)の得点を処理し、以下のことを行いなさい。① 90以上の得点を特定する。② 60から89までの得点を特定する。③ 80以上の得点を持つ生徒の人数を数える。 -
課題:
sample(1:100, 20)を使用して 20 個の数をランダムに生成するスクリプトを作成し、以下の数を数え出してください:① 偶数の数 (%% 2 == 0);② 3 で割り切れる数の数 (%% 3 == 0); ③ 偶数かつ3で割り切れる数の個数 (&—複合条件); ④ これらの数の合計と平均。



