16章 ベクトル
16.0 ライブラリの読み込み
library("tidyverse")
16.1 はじめに
16.2 ベクトルの基本
16.3 重要なアトミックベクトル
練習問題1 is.finite(x)
と!is.infinite(x)
の違いは何か。
is.finite(x)
と!is.infinite(x)
の違いは何か。is.finite()
はNA
, NaN
,Inf
,-Inf
は、NA
, NaN
をFALSE
として扱います。同じく、!is.infinite()
はNA
, NaN
をTRUE
として扱います。
x <- c(0, 1, NA, NaN, Inf, -Inf)
is.finite(x)
[1] TRUE TRUE FALSE FALSE FALSE FALSE
# !is.finite(x)
# [1] FALSE FALSE TRUE TRUE TRUE TRUE
# is.infinite(x)
# [1] FALSE FALSE FALSE FALSE TRUE TRUE
!is.infinite(x)
[1] TRUE TRUE TRUE TRUE FALSE FALSE
is.finite()
is.infinite()
NA
FALSE
FALSE
NaN
FALSE
FALSE
Inf
FALSE
TRUE
-Inf
FALSE
TRUE
練習問題2 dplyr::near()
のソースコードを読んで、機能を説明しなさい。
dplyr::near()
のソースコードを読んで、機能を説明しなさい。near()
は、完全に等価かどうかをチェックする代わりに、2つの数値の差が一定の許容範囲内であることをチェックします。デフォルトでは、許容誤差はコンピューターが表現できる最小の浮動小数点数(.Machine$double.eps
)の平方根に設定されています。
dplyr::near
function (x, y, tol = .Machine$double.eps^0.5)
{
abs(x - y) < tol
}
<bytecode: 0x1edb640>
<environment: namespace:dplyr>
.Machine$double.eps^0.5
[1] 1.490116e-08
>
.Machine$double.eps
[1] 2.220446e-16
練習問題3 論理ベクトルは3つの可能な値を取る。integer
に取り得る値はいくつあるのか。doble
に取り得る値はいくつあるか。
integer
に取り得る値はいくつあるのか。doble
に取り得る値はいくつあるか。整数ベクトルの場合、TRUE
、FALSE
、NA_integer_integer
の3つです。整数ベクトルで表現できる整数値の範囲は(2^31)-1
です。
c(TRUE, FALSE, NA_integer_)
[1] 1 0 NA
.Machine $ integer.max
[1] 2147483647
.Machine$double.xmax
[1] 1.8e+308
練習問題4 double
を整数に変換できるようにする少なくとも4つの関数を考えなさい。
double
を整数に変換できるようにする少なくとも4つの関数を考えなさい。整数に切り捨てるか丸めることによって、double
を整数に変換できます。
x <- c(-2.5, -1.5, 0, 1.5, 2.5)
round(x)
[1] -2 -2 0 2 2
floor(x)
[1] -3 -2 0 1 2
ceiling(x)
[1] -2 -1 0 2 3
trunc(x)
[1] -2 -1 0 1 2
signif(x, digits = 1)
[1] -2 -2 0 2 2
この例を見てわかるように、round()
は四捨五入ではありません。四捨五入であれば、2.5
は3
であるべきです。
round2 <- function(x, to_even = TRUE) {
q <- x %/% 1
r <- x %% 1
q + (r >= 0.5)
}
round(x)
[1] -2 -2 0 2 2
round2(x)
[1] -2 -1 0 2 3
丸め関数
処理内容
round(x, digits = 0)
IEEE式で丸めを行なう
ceiling(x)
x未満でない最小の整数を返す
floor(x)
x以上でない最大の整数を返す
signif(x, digits = 6)
digitsで指定された有効桁数に丸める
trunc(x)
xを0 へ向かって整数化する
練習問題5 {readr}パッケージ
のどの関数を使って文字列をlogical
、integer
、double
のベクトルに変えることができるか?
{readr}パッケージ
のどの関数を使って文字列をlogical
、integer
、double
のベクトルに変えることができるか?parse_logical()
、parse_integer()
、parse_number()
で変換できます。parse_logical()
は、1
やt
などもTRUE
とみなします。parse_integer()
は、0から始まっている文字型の数えあれば問題なくパースできますが、記号や小数点があると正確にパースできません。
parse_logical(c("TRUE", "FALSE", "1", "0", "true", "t", "NA"))
[1] TRUE FALSE TRUE FALSE TRUE TRUE NA
parse_integer(c("1235", "0134", "NA"))
[1] 1235 134 NA
parse_integer(c("1000", "$1,000", "$1,000.11", "10.00", "NA"))
警告: 3 parsing failures.
row col expected actual
2 -- an integer $1,000
3 -- an integer $1,000.11
4 -- no trailing characters .00
[1] 1000 NA NA NA NA
このような場合は、parse_number()
で変換できます。
parse_number(c("1000", "$1,000", "$1,000.11", "10.00", "NA"))
[1] 1000.00 1000.00 1000.11 10.00 NA
16.4 アトミックベクトルを使う
練習問題1 mean(is.na(x))
はどのように機能するのか。sum(!is.finite(x))
とどう違うのか。
mean(is.na(x))
はどのように機能するのか。sum(!is.finite(x))
とどう違うのか。mean(is.na(x))
は、ベクトル内の欠損値の割合を計算します。
x <- c(-1, 0, 1,-Inf, Inf, NA, NaN)
mean(is.na(x))
[1] 0.2857143
sum(!is.finite(x))
は、NA
、NaN
、Inf
に等しいベクトル内の要素数を計算します。
sum(!is.finite(x))
[1] 4
!is.finite(x)
[1] FALSE FALSE FALSE TRUE TRUE TRUE TRUE
練習問題2 is.vector()
のドキュメントを読んで、is.atomic()
のアトミックベクトルの定義と異なるのか説明しなさい。
is.vector()
のドキュメントを読んで、is.atomic()
のアトミックベクトルの定義と異なるのか説明しなさい。is.vector()
は、オブジェクトにname
以外の属性(attr
)がないかどうかを確認します。したがって、 list
はTRUE
として扱われます。
is.vector(list(a = 1, b = 1))
[1] TRUE
vec <- 1:10
attr(vec, 'foo') <- 'bar'
is.vector(vec);
[1] FALSE
is.atomic()
は "logical"、 "integer"、 "numeric"、 "complex"、 "character"、 "raw"どうかを論理判定します。属性を持つかどうかは関係ありません。
is.atomic(vec)
[1] TRUE
練習問題3 setNames()
とpurrr::set_names()
を比較しなさい。
setNames()
とpurrr::set_names()
を比較しなさい。この2つの関数は、ベクトルの要素に名前をつけることができます。purrr::set_names()
は関数を使える点で異なります。
setNames(1:4, c("a", "b", "c", "d"))
a b c d
1 2 3 4
purrr::set_names(1:4, c("a", "b", "c", "d"))
a b c d
1 2 3 4
purrr::set_names(c(a = 1, b = 2, c = 3, d = 4), toupper)
A B C D
1 2 3 4
練習問題4 入力としてベクトルを受け取る関数を作成しなさい。
最後の値を抽出するために
[
または[[
を使うべきか?
単一の要素を抽出するために[[
を使います。[
または[[
はリストが絡んでいる場合、注意が必要です。
last_value <- function(x) {
# check for case with no length
if (length(x)) {
x[[length(x)]]
} else {
x
}
}
last_value(1)
[1] 1
last_value(1:10)
[1] 10
偶数位置の要素
even_indices <- function(x) {
if (length(x)) {
x[seq_along(x) %% 2 == 0]
} else {
x
}
}
even_indices(1:10)
[1] 2 4 6 8 10
最後の値を除くすべての要素
not_last <- function(x) {
n <- length(x)
if (n) {
x[-n]
} else {
# n == 0
x
}
}
not_last(1:3)
[1] 1 2
偶数のみ(および欠損値なし)
欠損値を含む場合も多いので、欠損値を含んだ状態で作ります。
even_numbers <- function(x) {
x[x %% 2 == 0]
}
even_numbers(c(-4:4, NA, NaN, Inf, -Inf))
[1] -4 -2 0 2 4 NA NA NA NA
練習問題5 x[-which(x > 0)]
はx[x <= 0]
とどう異なるのか。
x[-which(x > 0)]
はx[x <= 0]
とどう異なるのか。これらの式は、欠損値を扱う方法が異なります。また、which()
は条件に一致する要素のインデックスを返し、等号を要素に対して使うと、TRUE or FALSE
が返されます。
x <- c(-1:1, Inf, -Inf, NaN, NA)
which(x > 0)
[1] 3 4
x[-which(x > 0)]
[1] -1 0 -Inf NaN NA
x <= 0
[1] TRUE TRUE FALSE FALSE TRUE NA NA
x[x <= 0]
[1] -1 0 -Inf NA NA
練習問題6 ベクトルの長さよりも大きい正の整数でサブセット化するとどうなるか。存在しない名前でサブセットするとどうなるか。
存在しないインデックスや名前でサブセットすると、エラーが表示されます。
x <- 1:10
x[[100]]
[[100]] でエラー: 添え字が許される範囲外です
x <- c(a = 10, b = 20)
x[["c"]]
x[["c"]] でエラー: 添え字が許される範囲外です
16.5 再帰ベクトル(リスト)
練習問題1 次のlist
を入れ子集合として描きます。
list
を入れ子集合として描きます。list(a, b, list(c, d), list(e, f))
a
とb
と同じ階層にc
とd
が入ったリストと、別にe
とf
が入ったリストがある。
list(a, b, list(c, d), list(e, f))
[[1]]
[1] "a"
[[2]]
[1] "b"
[[3]]
[[3]][[1]]
[1] "c"
[[3]][[2]]
[1] "d"
[[4]]
[[4]][[1]]
[1] "e"
[[4]][[2]]
[1] "f"
list(list(list(list(list(list(a))))))
6重にネストしているリスト。
list(list(list(list(list(list(a))))))
[[1]]
[[1]][[1]]
[[1]][[1]][[1]]
[[1]][[1]][[1]][[1]]
[[1]][[1]][[1]][[1]][[1]]
[[1]][[1]][[1]][[1]][[1]][[1]]
[1] "a"
練習問題2 list
をサブセット化しているかのようにtibble
をサブセットするとどうなるのか。リストとtibble
の主な違いは何か?
単一の要素をベクトルとして抽出するためには、[[
を使います。リストとtibble
の違いは、リストは異なる長さのベクトルやデータフレームを内包できますが、tibble
はデータフレームと同じで、異なる長さでは保持できません。
x <- tibble(a = 1:2, b = 3:4)
x
# A tibble: 2 x 2
a b
<int> <int>
1 1 3
2 2 4
x[["a"]]
[1] 1 2
x["a"]
# A tibble: 2 x 1
a
<int>
1 1
2 2
16.6 属性
16.7 拡張ベクトル
練習問題1 hms::hms(3600)
は何を返しますか。拡張ベクトルはどのような基本型の上に構築され、どんな属性を使うのか?
hms::hms(3600)
は何を返しますか。拡張ベクトルはどのような基本型の上に構築され、どんな属性を使うのか?hms
クラスのオブジェクトを返し、時刻を%H:%M:%S
の形式で出力します。
x <- hms::hms(3600)
class(x)
[1] "hms" "difftime"
x
01:00:00 # 1 hour = 3600 min
練習問題2 長さの異なる列を持つtibble
を試してみてください。何が起こるのですか?
tibble
を試してみてください。何が起こるのですか?長さの異なる2つのベクトルを使用してtibble
を作成しようとすると、tibble
はエラーを返します。
x <- tibble(a = 1:2, b = 3:5)
エラー: Tibble columns must have consistent lengths, only values of length one are recycled:
* Length 2: Column `a`
* Length 3: Column `b`
Call `rlang::last_error()` to see a backtrace
長さが短い場合、リサイクル規則によって、足りていな分をリサイクルします。
x <- tibble(a = 1, b = 3:5)
x
# A tibble: 3 x 2
a b
<dbl> <int>
1 1 3
2 1 4
3 1 5
練習問題3 上記の定義に基づいて、list
をtibble
の列として持つことは問題ありませんか。
list
をtibble
の列として持つことは問題ありませんか。上記のエラーメッセージは異なる長さを持つベクトルに関するものです。doble
、character
、integer
、logical
、date
などの異なる型のベクトルをリストとして持つこともtibble
は可能です。
tibble(x = 1:6,
y = list(1.11, "a", 1L, TRUE, today(), list(1:3)))
# A tibble: 6 x 2
x y
<int> <list>
1 1 <dbl [1]>
2 2 <chr [1]>
3 3 <int [1]>
4 4 <lgl [1]>
5 5 <date [1]>
6 6 <list [1]>
最終更新
役に立ちましたか?