はじめに
機械学習の勉強を始めたVBAユーザです。
備忘録としてPython・Rの文法をVBAと比較しながらまとめていきたいと思います。
目次
条件分岐
今回は、条件分岐についてです。
コメントをいただいて、追記しました。
if文
条件分岐(主に、if文)についてです。
Python
x = 0
if x == 0:
print(0)
# 0
if x == 0:
print(0)
else:
print(1)
# 0
if x == 0:
print(0)
elif x == 1:
print(1)
elif x == 2:
print(2)
else:
print(3)
# 0
if x in (0,1,2):
print(x)
else:
print(3)
# 0
Pythonにはswitch文、case文はなさそうです。
なお、Pythonでは、If文のまとまり(ブロック)を(次のRのように{``}
で囲んだり、VBAのようにIf
ではじまってEnd If
で閉じたり、というような方法ではなく)インデント(字下げ)で表現します(If文に限らず、他の制御構文(繰り返しのFor文)でも同様です。)。
R
x <- 0
if (x == 0) {
print(0)
}
# 0
if (x == 0) {
print(0)
} else {
print(1)
}
# 0
if (x == 0) {
print(0)
} else if (x == 1) {
print(1)
} else if (x == 2) {
print(2)
} else {
print(3)
}
# 0
if (x %in% c(0,1,2)) {
print(x)
} else {
print(3)
}
Rには、switch
関数がありますが、使いづらそうです(参考:R-Tips)。
VBA
x = 0
If x = 0 Then
Debug.Print 0
End If
' 0
If x = 0 Then
Debug.Print 0
Else
Debug.Print 1
End If
' 0
If x = 0 Then
Debug.Print 0
ElseIf x = 1 Then
Debug.Print 1
ElseIf x = 2 Then
Debug.Print 2
Else
Debug.Print 3
End If
' 0
Select Case x
Case 0
Debug.Print 0
Case 1
Debug.Print 1
Case 2
Debug.Print 2
Case Else
Debug.Print 3
End Select
' 0
Select Case x
Case 0, 1, 2
Debug.Print x
Case Else
Debug.Print 3
End Select
' 0
Select Case x
Case 0 To 2
Debug.Print x
Case Else
Debug.Print 3
End Select
'0
Select Case x
Case Is <= 2
Debug.Print x
Case Else
Debug.Print 3
End Select
' 0
Debug.Print Switch(x = 0, 0)
' 0
Debug.Print Switch(x = 0, 0, 1, 1)
' 0
Debug.Print Switch(x = 0, 0, x = 1, 1, x = 2, 2, True, 3)
' 0
Debug.Print Switch(x <= 2, x, True, 3)
' 0
VBAにはSelect Case文があります。Switch関数もあります。
case文の実現
(コメントをいただいて追記しました。)
Python、Rにはcase文がありませんが、標準機能を使って実現できます。
例として、日本語の曜日(aaa)を英語の曜日(ddd)に変換して出力することを考えます1。
aaa | aaaa | ddd | dddd |
---|---|---|---|
日 | 日曜日 | Sun | Sunday |
月 | 月曜日 | Mon | Monday |
火 | 火曜日 | Tue | Tuesday |
水 | 水曜日 | Wed | Wednesday |
木 | 木曜日 | Thu | Thursday |
金 | 金曜日 | Fri | Friday |
土 | 土曜日 | Sat | Saturday |
VBA
VBAでは、Select Case
文やSwitch
関数を使って書くことができます。
s = "金"
Select Case s
Case "日": Debug.Print "Sun"
Case "月": Debug.Print "Mon"
Case "火": Debug.Print "Tue"
Case "水": Debug.Print "Wed"
Case "木": Debug.Print "Thu"
Case "金": Debug.Print "Fri"
Case "土": Debug.Print "Sat"
Case Else: Debug.Print "not found"
End Select
' Fri
Debug.Print Switch(s = "日", "Sun", _
s = "月", "Mon", _
s = "火", "Tue", _
s = "水", "Wed", _
s = "木", "Thu", _
s = "金", "Fri", _
s = "土", "Sat", _
True, "not found")
' Fri
これと同じことを、Python、Rの標準機能で実現してみます。
Python
Pythonでは、リスト(list)を使って次のように実現できます。
aaa = ['日', '月', '火', '水', '木', '金', '土']
ddd = ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat']
s = '金'
t = '銀'
print(s in aaa) # True
print(t in aaa) # False
print(aaa.index(s)) # 5
# print(aaa.index(t)) # エラー
print(ddd[aaa.index(s)]) # Fri
def aaa_to_ddd(value):
if value in aaa:
return ddd[aaa.index(value)]
else:
return 'not found'
print(aaa_to_ddd(s)) # Fri
print(aaa_to_ddd(t)) # not found
def print_ddd(value):
if value in aaa:
print(ddd[aaa.index(value)])
else:
print('not found')
print_ddd(s) # Fri
print_ddd(t) # not found
Pythonでは、辞書(dictionary)を使っても実現できます。こちらの方が簡単に書けます。
aaa = ['日', '月', '火', '水', '木', '金', '土']
ddd = ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat']
aaa_ddd = dict(zip(aaa, ddd)) # 辞書
print(aaa_ddd)
# {'日': 'Sun', '月': 'Mon', '火': 'Tue', '水': 'Wed', '木': 'Thu', '金': 'Fri', '土': 'Sat'}
s = '金'
t = '銀'
print(aaa_ddd[s]) # Fri
# print(aaa_ddd[t]) # エラー
print(aaa_ddd.get(s)) # Fri
print(aaa_ddd.get(t)) # None
def aaa_to_ddd(value):
if value in aaa:
return aaa_ddd[value]
else:
return 'not found'
print(aaa_to_ddd(s)) # Fri
print(aaa_to_ddd(t)) # not found
def aaa_to_ddd(value):
if value in aaa:
return aaa_ddd.get(value)
else:
return 'not found'
print(aaa_to_ddd(s)) # Fri
print(aaa_to_ddd(t)) # not found
def aaa_to_ddd(value):
return aaa_ddd.get(value, 'not found')
print(aaa_to_ddd(s)) # Fri
print(aaa_to_ddd(t)) # not found
def print_ddd(value):
print(aaa_ddd.get(value, 'not found'))
print_ddd(s) # Fri
print_ddd(t) # not found
R
Rでは文字列ベクトルを使って実現できます。
aaa = c("日", "月", "火", "水", "木", "金", "土")
ddd = c("Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat")
s <- "金"
t <- "銀"
s %in% aaa # TRUE
t %in% aaa # FALSE
aaa == s # FALSE FALSE FALSE FALSE FALSE TRUE FALSE
aaa == t # FALSE FALSE FALSE FALSE FALSE FALSE FALSE
which(aaa == s) # 6
which(aaa == t) # integer(0)
aaa[which(aaa == s)] # "金"
aaa[which(aaa == t)] # character(0)
aaa[aaa == s] # "金"
aaa[aaa == t] # character(0)
aaa_to_ddd <- function(value) {
if (value %in% aaa) {
return(ddd[aaa == value]) # ddd[aaa == value][1]
} else {
return("not found")
}
}
aaa_to_ddd(s) # "Fri"
aaa_to_ddd(t) # "not found"
print_ddd <- function(value) {
if (value %in% aaa) {
print(ddd[aaa == value])
} else {
print("not found")
}
}
print_ddd(s) # "Fri"
print_ddd(t) # "not found"
VBA
Function aaa_to_ddd_1(value As String) As String
' Case文を使って
Select Case value
Case "日": aaa_to_ddd_1 = "Sun"
Case "月": aaa_to_ddd_1 = "Mon"
Case "火": aaa_to_ddd_1 = "Tue"
Case "水": aaa_to_ddd_1 = "Wed"
Case "木": aaa_to_ddd_1 = "Thu"
Case "金": aaa_to_ddd_1 = "Fri"
Case "土": aaa_to_ddd_1 = "Sat"
Case Else: aaa_to_ddd_1 = "not found"
End Select
End Function
Function aaa_to_ddd_2(value As String) As String
' Switch関数を使って
Dim v As Variant
v = Switch(value = "日", "Sun", _
value = "月", "Mon", _
value = "火", "Tue", _
value = "水", "Wed", _
value = "木", "Thu", _
value = "金", "Fri", _
value = "土", "Sat")
If IsNull(v) Then
v = "not found"
End If
aaa_to_ddd_2 = v
End Function
Function aaa_to_ddd_3(value As String) As String
' 配列を使って
Dim aaa As Variant
Dim ddd As Variant
Dim i As Integer
Dim s As String
aaa = Array("日", "月", "火", "水", "木", "金", "土")
ddd = Array("Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat")
s = "not found"
For i = LBound(aaa) To UBound(aaa)
If value = aaa(i) Then
s = ddd(i)
End If
Next i
aaa_to_ddd_3 = s
End Function
Sub print_ddd(value As String)
' Case文を使って
Select Case value
Case "日": Debug.Print "Sun"
Case "月": Debug.Print "Mon"
Case "火": Debug.Print "Tue"
Case "水": Debug.Print "Wed"
Case "木": Debug.Print "Thu"
Case "金": Debug.Print "Fri"
Case "土": Debug.Print "Sat"
Case Else: Debug.Print "not found"
End Select
End Sub
Sub test_case()
Dim s As String
Dim t As String
s = "金"
Select Case s
Case "日": Debug.Print "Sun"
Case "月": Debug.Print "Mon"
Case "火": Debug.Print "Tue"
Case "水": Debug.Print "Wed"
Case "木": Debug.Print "Thu"
Case "金": Debug.Print "Fri"
Case "土": Debug.Print "Sat"
Case Else: Debug.Print "not found"
End Select
' Fri
Debug.Print Switch(s = "日", "Sun", _
s = "月", "Mon", _
s = "火", "Tue", _
s = "水", "Wed", _
s = "木", "Thu", _
s = "金", "Fri", _
s = "土", "Sat", _
True, "not found")
' Fri
s = "金"
t = "銀"
Debug.Print aaa_to_ddd_1(s) ' Fri
Debug.Print aaa_to_ddd_2(s) ' Fri
Debug.Print aaa_to_ddd_3(s) ' Fri
Debug.Print aaa_to_ddd_1(t) ' not found
Debug.Print aaa_to_ddd_2(t) ' not found
Debug.Print aaa_to_ddd_3(t) ' not found
Call print_ddd(s) ' Fri
Call print_ddd(t) ' not found
End Sub
まとめ
一覧
各言語で使用するステートメント等を一覧にまとめます。比較のために、EXCELでの計算も示しました。
条件分岐
Python | R | VBA | EXCEL | |
---|---|---|---|---|
if文 |
if P: ... elif Q: ... elif R: ... else: ...
|
if (P) { ... } else if (Q) { ... } else if (R) { ... } else { ... }
|
If P Then ... ElseIf Q Then ... ElseIf R Then ... Else ... End If
|
=IF(P,..., IF(Q,..., IF(R,..., ...)))
|
switch文 |
Select Case X Case p ... Case q ... Case r ... Case Else ... End Select
|
=SWITCH(X, p,..., q,..., r,... ,...)
|
プログラム全体
参考までに使ったプログラムの全体を示します。
Python
# 条件分岐
x = 0
if x == 0:
print(0)
# 0
if x == 0:
print(0)
else:
print(1)
# 0
if x == 0:
print(0)
elif x == 1:
print(1)
elif x == 2:
print(2)
else:
print(3)
# 0
if x in (0,1,2):
print(x)
else:
print(3)
# 0
R
# 条件分岐(If)
x <- 0
if (x == 0) {
print(0)
}
# 0
if (x == 0) {
print(0)
} else {
print(1)
}
# 0
if (x == 0) {
print(0)
} else if (x == 1) {
print(1)
} else if (x == 2) {
print(2)
} else {
print(3)
}
# 0
if (x %in% c(0,1,2)) {
print(x)
} else {
print(3)
}
# 0
VBA
Sub test_conditional_branch()
Dim x As Integer
' 条件分岐
x = 0
If x = 0 Then
Debug.Print 0
End If
' 0
If x = 0 Then
Debug.Print 0
Else
Debug.Print 1
End If
' 0
If x = 0 Then
Debug.Print 0
ElseIf x = 1 Then
Debug.Print 1
ElseIf x = 2 Then
Debug.Print 2
Else
Debug.Print 3
End If
' 0
Select Case x
Case 0
Debug.Print 0
Case 1
Debug.Print 1
Case 2
Debug.Print 2
Case Else
Debug.Print 3
End Select
' 0
Select Case x
Case 0, 1, 2
Debug.Print x
Case Else
Debug.Print 3
End Select
' 0
Select Case x
Case 0 To 2
Debug.Print x
Case Else
Debug.Print 3
End Select
'0
Select Case x
Case Is <= 2
Debug.Print x
Case Else
Debug.Print 3
End Select
' 0
Debug.Print Switch(x = 0, 0)
' 0
Debug.Print Switch(x = 0, 0, 1, 1)
' 0
Debug.Print Switch(x = 0, 0, x = 1, 1, x = 2, 2, True, 3)
' 0
Debug.Print Switch(x <= 2, x, True, 3)
' 0
End Sub
参考
- Python
- R
- RjpWiki
-
R-Tips
- 29. 条件分岐
-
13. ベクトル要素へのアクセス:
which
-
14. ベクトル計算
%in%
- VBA
- Office VBA リファレンス
-
"aaa","aaaa","ddd","dddd" はExcelの書式の表示形式の文字列です。 ↩