Julia 入門01 -- R と比較して

以下は，R 入門のために書かれた

https://www.jaysong.net/rprogramming/

を，Julia ではこんな風になるよということで書いたものである。

#################

R の入門というページは多く存在する。

R に入門しようとしている人 ... Julia にしませんか？

#ベクトルを使用する。

R では，ベクトルは c() でも作成できる。

```R
myVec1 <- c(1, 2, 3, 4, 5) # myVec1 <- 1:5も同じ
```

Julia では '配列' と総称する。

Julia では [ ] でくくる。

```Julia
myVec1 = [1, 2, 3, 4, 5] # myVec1 = 1:5 も 'ほぼ同じ'
```

ほぼ同じというのは

```Julia
myVec1 = [1, 2, 3, 4, 5]
```
は， [1, 2, 3, 4, 5] というベクトルを作るが，

```Julia
myVec2 = 1:5
```

は実際にメモリ上にベクトルを確保しない。

これは大きな違だ。例えば

```Julia
myVec1 = [1, 2, 途中省略, 100000]
```

というのを定義すると，かなり大きな領域が確保される。

```Julia
myVec2 = 1:100000
```

を比較すると，長さ length() は確かに 5, 100000 と明らかに長さは違う。

```Julia
length(1:5)      # 5
length(1:100000) # 100000
```

しかし，実際に確保されているメモリのサイズは全く同じだ。

```Julia
Base.summarysize(1:5)      # 16
Base.summarysize(1:100000) # 16
```

和をとってみても，ちゃんと期待する値が得られる。

```Julia
sum(1:5)      # 15         = 5*(5+1)÷2
sum(1:100000) # 5000050000 = 100000*(10000+1)÷2
```

1:100000 までの和を愚直に計算するときに，R では

```R
s = 0
for (i in 1:100000) {
    s = s + i
}
print(s)
```

とする。

Julia では

```Julia
s = 0
for i in 1:100000
    s = s + i
end
println(s) # 5000050000
```

字面はよく似ている（for ループについては後述）。

しかし，R での 1:100000 と Julia での 1:100000 は使用するメモリーの量が全く違う。

なお，R の 1:100000 と同じ，実際にメモリ状に配置するやりかたは

```Julia
myVec3 = collect(1:100000)
```

である。しかし，実際に消費されるメモリ量は 800040 にもなる。

```Julia
Base.summarysize(myVec3) # 800040
```

前のプログラムで 1:100000 だったところを collect(1:100000) にしても，当然同じ結果になる。

```Julia
s = 0
for i in collect(1:100000)
    s = s + i
end
println(s) # 5000050000
```

#欠損値を含むベクトル

欠損値は R では NA で表す。

``` R
myVec2 <- c(1, 2, 3, NA, 5)
```

このベクトルの総和を求める関数は R では sum() である。しかし，

``` R
sum(myVec2) # NA
```

となってしまう。NA を除いて集計するためには，

``` R
sum(myVec2, na.rm = TRUE) # 11
```

としなければならない。

Julia では 欠損値を missing で表す。

```Julia
myVec2 = [1, 2, 3, missing, 5]
```

総和を求める関数は同じ名前の sum() であるが，R の場合と同じく，そのまま使っても期待される結果は得られない。

```Julia
sum(myVec2)              # missing
```

missing を除いて計算するためには skipmissing() を使用する。

```Julia
sum(skipmissing(myVec2)) # 11
```

統計関数は mean(), variance(), std(), median() などがあるが，Julia で使用する前には以下のおまじないが必要だ。
R でいえば，特定のパッケージを使用するときには 最初に library(ライブラリ名) をする必要があるが，Julia では mean() すら特定のおまじないが必要ということだ。

```Julia
using Statistics # おまじない
mean(skipmissing(myVec2))   # 2.75
var(skipmissing(myVec2))    # 2.9166666666666665
std(skipmissing(myVec2))    # 1.707825127659933
median(skipmissing(myVec2)) # 2.5
```

もちろん，missing を含まない場合には，skipmissing() を適用する必要はない。

```Julia
x = [1, 3, 6, 9]
mean(x) # 4.75
```

#プログラムの書き方

- オブジェクト名（代表的には，変数名，関数名など）は Julia では 英小文字で始まり，英子文字・数字が続くというのがスタンダード。
- 複数ワードで構成される場合は R では first_order のように _ で繋ぐことが多いが，Julia では firstorder というように続けて書く。また，それぞれの単語は省略しない。

この点では，R とはかなり思想が違う。

改行とインデントについては R と同じ。

代入は，R では基本的に <- が使われるが，最近では = を使うほうが多くなっているようだ。Julia では = を使う。

for 文は R では

``` R
for (変数 in ベクトル) {
    処理
}
```

であるが，Julia では

```Julia
for 変数 in イテラブル
    処理
end
```

である。

- for の後の ( ) で囲まれる部分は ( ) は書かない（書いてもエラーではないが）。
- R の ベクトルが Julia ではイテラブルになっている。イテラブルは前述したような 1:n のようなもので，これは R のベクトルではなかった。
- また，R での開始を表す { がなくて，終了の } が end である。

しかし，両者はよく似ている（Julia は Python よりは R に近い）。

なお，イテラブルはベクトル（配列）も含むので，以下の例は配列に含まれる全ての要素を出力する。この例は R とほとんど同じといってよいだろう。

```Julia
for fruit in ["apple", "orange", "grape", "melon"]
    println(fruit)
end
```

または，

```Julia
fruit = ["apple", "orange", "grape", "melon"]
for i in 1:length(fruit)
    println(fruit[i])
end
```

#多重 for ループ

R がわかっていれば，少しの違いであることがわかる。

``` Julia
for i = 1:3
    for j = 1:5
        println(i*j)
    end
end
```

また，この場合は特徴的に以下のように書くこともできる。

```Julia
for i = 1:3, j = 1:5
    println(i*j)
end
```

#while による反復

R では

```R 
while(条件) {
    条件が満たされる場合の処理
}
```

であるが，Julia では

```Julia
while 条件
    条件が満たされる場合の処理
end
```

である。

for ループの場合と同じく，

- while の後の ( ) で囲まれる部分は ( ) は書かない（書いてもエラーではないが）。
- R での開始を表す { がなくて，終了の } が end である。

しかし，両者はよく似ている（Julia は Python よりは R に近い）。

以下のプログラムでは 1〜5 が出力される。

```Julia
i = 1
while i <＝ 5
    println(i)
    i = i + 1 # i += 1 とも書ける
end
```

途中でループを脱出する場合には break, ループをスキップするときは continue を使う。

#条件分岐

R では

```R 
if (条件1) {
    条件1が満たされた場合の処理内容
} else if (条件2) {
    条件2が満たされた場合の処理内容
} else if (条件3) {
    条件3が満たされた場合の処理内容
}
  :
} else {
    それまでの条件のいずれも当てはまらなかった場合の処理内容
}
```

for や while の場合と同じく

- 条件は ( ) で囲まない（囲んでもえらーbにはならないが）
- 複文の開始の { はない
- else if ではなく elseif である
- 最後の } は end である

R が分かっている人には自明だが，elseif も else も必要なければ書かない。

#swich 文による条件分岐

R の switch 文は非常にできが悪い。使っている人もほとんどいないのではないだろうか。

Julia では https://blog.goo.ne.jp/r-de-r/e/c254cfc909f5cbf5bf923e50df1a4173 のように使う。

#関数の作成

R では

```R 
myPower <- function(x) {
  x^2
}
```

のように定義するが，Julia では

```Julia
function myPower(x)
    x^2
end
```

とする。

- 複文の開始の { はなくて，終了の } は end とする。

この限りにおいてはほぼ同じである。

なお，このように短い関数の定義は

```Julia
myPower(x) = x^2
```

のように簡潔に書ける。