ベクトル化
最終更新日:2024-11-22 | ページの編集
所要時間: 25分
概要
質問
- ベクトルのすべての要素に一度に操作を行うにはどうすればよいですか?
目的
- Rにおけるベクトル化された操作を理解する。
Rの関数のほとんどはベクトル化されており、ループを使用して各要素に対して1つずつ処理を行う必要なく、ベクトルのすべての要素に対して操作を実行します。 これにより、コードが簡潔で読みやすく、エラーが少なくなります。
R
x <- 1:4
x * 2
出力
[1] 2 4 6 8
乗算がベクトルの各要素に対して行われました。
2つのベクトルを加えることもできます:
R
y <- 6:9
x + y
出力
[1] 7 9 11 13
x
の各要素が対応する y
の要素と加算されました:
次に、ループを使用して2つのベクトルを加算する方法を示します:
R
output_vector <- c()
for (i in 1:4) {
output_vector[i] <- x[i] + y[i]
}
output_vector
出力
[1] 7 9 11 13
ベクトル化された操作を使用した出力と比較してください。
R
sum_xy <- x + y
sum_xy
出力
[1] 7 9 11 13
チャレンジ 1
gapminder
データセットの pop
列を使用してみましょう。
gapminder
データフレームに新しい列を作成し、
人口を100万人単位で表示してください。
データフレームの先頭または末尾を確認して、正しく動作したか確認してください。
gapminder
データセットの pop
列を使用してみましょう。
gapminder
データフレームに新しい列を作成し、
人口を100万人単位で表示してください。
データフレームの先頭または末尾を確認して、正しく動作したか確認してください。
R
gapminder$pop_millions <- gapminder$pop / 1e6
head(gapminder)
出力
country year pop continent lifeExp gdpPercap pop_millions
1 Afghanistan 1952 8425333 Asia 28.801 779.4453 8.425333
2 Afghanistan 1957 9240934 Asia 30.332 820.8530 9.240934
3 Afghanistan 1962 10267083 Asia 31.997 853.1007 10.267083
4 Afghanistan 1967 11537966 Asia 34.020 836.1971 11.537966
5 Afghanistan 1972 13079460 Asia 36.088 739.9811 13.079460
6 Afghanistan 1977 14880372 Asia 38.438 786.1134 14.880372
チャレンジ 2
単一のグラフ上で、すべての国の人口(単位は100万人)を年に対してプロットしてください。 どの国がどれかを識別する必要はありません。
次に、中国、インド、インドネシアに対してのみグラフ化を行ってください。 こちらもどの国がどれかを識別する必要はありません。
人口(単位は100万人)を年に対してプロットして、プロットスキルをリフレッシュしましょう。
R
ggplot(gapminder, aes(x = year, y = pop_millions)) +
geom_point()
R
countryset <- c("China","India","Indonesia")
ggplot(gapminder[gapminder$country %in% countryset,],
aes(x = year, y = pop_millions)) +
geom_point()
比較演算子、論理演算子、多くの関数もまたベクトル化されています:
比較演算子
R
x > 2
出力
[1] FALSE FALSE TRUE TRUE
論理演算子
R
a <- x > 3 # または、明確にするために a <- (x > 3)
a
出力
[1] FALSE FALSE FALSE TRUE
ヒント:論理ベクトルの便利な関数
any()
はベクトル内に1つでも TRUE
が含まれていれば TRUE
を返します。all()
はベクトル内のすべての要素が TRUE
の場合にのみ TRUE
を返します。
ほとんどの関数はベクトルに対して要素ごとに操作を行います:
関数
R
x <- 1:4
log(x)
出力
[1] 0.0000000 0.6931472 1.0986123 1.3862944
ベクトル化された操作は行列の要素ごとにも動作します:
R
m <- matrix(1:12, nrow=3, ncol=4)
m * -1
出力
[,1] [,2] [,3] [,4]
[1,] -1 -4 -7 -10
[2,] -2 -5 -8 -11
[3,] -3 -6 -9 -12
ヒント:要素ごとの積と行列積の違い
重要:*
演算子は要素ごとの積を行います!
行列積を行うには、%*%
演算子を使用する必要があります:
R
m %*% matrix(1, nrow=4, ncol=1)
出力
[,1]
[1,] 22
[2,] 26
[3,] 30
R
matrix(1:4, nrow=1) %*% matrix(1:4, ncol=1)
出力
[,1]
[1,] 30
行列代数についての詳細は、Quick-R のリファレンスガイド を参照してください。
チャレンジ 3
次の行列を使用して:
R
m <- matrix(1:12, nrow=3, ncol=4)
m
出力
[,1] [,2] [,3] [,4]
[1,] 1 4 7 10
[2,] 2 5 8 11
[3,] 3 6 9 12
以下を実行するとどうなるか予想してください:
m ^ -1
m * c(1, 0, -1)
m > c(0, 20)
m * c(1, 0, -1, 2)
出力が予想と違った場合は、ヘルパーに尋ねてください!
次の行列を使用して:
R
m <- matrix(1:12, nrow=3, ncol=4)
m
出力
[,1] [,2] [,3] [,4]
[1,] 1 4 7 10
[2,] 2 5 8 11
[3,] 3 6 9 12
以下を実行するとどうなるか予想してください:
m ^ -1
出力
[,1] [,2] [,3] [,4]
[1,] 1.0000000 0.2500000 0.1428571 0.10000000
[2,] 0.5000000 0.2000000 0.1250000 0.09090909
[3,] 0.3333333 0.1666667 0.1111111 0.08333333
m * c(1, 0, -1)
出力
[,1] [,2] [,3] [,4]
[1,] 1 4 7 10
[2,] 0 0 0 0
[3,] -3 -6 -9 -12
m > c(0, 20)
出力
[,1] [,2] [,3] [,4]
[1,] TRUE FALSE TRUE FALSE
[2,] FALSE TRUE FALSE TRUE
[3,] TRUE FALSE TRUE FALSE
チャレンジ 4
次の分数列の合計を計算したいとします:
R
x = 1/(1^2) + 1/(2^2) + 1/(3^2) + ... + 1/(n^2)
これを手で書き出すのは面倒で、高い値の n に対しては不可能です。 ベクトル化を使用して、n=100 の場合の x を計算してください。 n=10,000 の場合の合計はどうなりますか?
次の分数列の合計を計算したいとします:
R
x = 1/(1^2) + 1/(2^2) + 1/(3^2) + ... + 1/(n^2)
これを手で書き出すのは面倒で、高い値の n に対しては不可能です。 ベクトル化を使用して、n=100 の場合の x を計算してください。 n=10,000 の場合はどうでしょうか?
R
sum(1/(1:100)^2)
出力
[1] 1.634984
R
sum(1/(1:1e04)^2)
出力
[1] 1.644834
R
n <- 10000
sum(1/(1:n)^2)
出力
[1] 1.644834
同じ結果を関数を使用して得ることもできます:
R
inverse_sum_of_squares <- function(n) {
sum(1/(1:n)^2)
}
inverse_sum_of_squares(100)
出力
[1] 1.634984
R
inverse_sum_of_squares(10000)
出力
[1] 1.644834
R
n <- 10000
inverse_sum_of_squares(n)
出力
[1] 1.644834
ヒント:長さが異なるベクトルに対する操作
長さが異なるベクトルに対しても操作を実行できます。 これはリサイクルと呼ばれるプロセスを通じて行われます。 このプロセスでは、小さいベクトルが自動的に繰り返されて大きいベクトルの長さに一致します。 大きいベクトルが小さいベクトルの倍数ではない場合、Rは警告を出します。
R
x <- c(1, 2, 3)
y <- c(1, 2, 3, 4, 5, 6, 7)
x + y
警告
Warning in x + y: longer object length is not a multiple of shorter object
length
出力
[1] 2 4 6 5 7 9 8
ベクトル x
はベクトル y
の長さに一致するようにリサイクルされました:
まとめ
- ループの代わりにベクトル化された操作を使用する。