R(変数とオブジェクト)

2024年3月12日 (火)

[R]変数(ベクトル)を使用する

プログラミング言語やスクリプト言語における変数とは、いろいろな計算や処理のために数値や文字などを一時的に格納しておくためのもの。変数には任意の名前を付けることができる。作成できる変数の数に制限はなく、必要な種類の変数を必要なだけ作成することができる。

C++やJavaなどのプログラミング言語と異なり、Rでは変数を作成するための変数の宣言はしなくてもよい(してもよい)。変数に値を代入することが宣言を兼ねている。なお、Rには変数というものは存在せず、変数に相当するものはベクトル(厳密にはオブジェクト)という。代入には代入演算子<-を使う。=も使うことができるが、推奨しない。

> n
エラー: オブジェクト 'n' がありません
> s
エラー: オブジェクト 's' がありません
> n <- 58
> s <- "メイショウドトウ役の和多田美咲さんかわいい"
> n
[1] 58
> s
[1] "メイショウドトウ役の和多田美咲さんかわいい"

2024年3月11日 (月)

[R]代入した結果を表示する

コマンドラインでベクトルなどに値を代入すると、画面には何も表示されないが、この代入を( )(括弧)で囲むと、代入した結果を表示するようになる。デバッグ時などに利用すると便利。

> s1 <- "鈴木みのり"
> print(s1)
[1] "鈴木みのり"
> (s2 <- "和多田美咲")
[1] "和多田美咲"
> print(s2)
[1] "和多田美咲"

2024年1月 8日 (月)

[R]ベクトルやデータフレームをファイルに保存して、後で読み込んで再利用する

readrパッケージのwrite_rds関数を使うことで、オブジェクト(ベクトルやデータフレームなど)をファイルに保存することができる。このファイルに保存した内容は、後(Rの再起動後も可)でread_rds関数を使ってその環境に読み込み再利用することができる。save関数と異なり、一つのオブジェクトしか保存することができず、readRDS関数で読み込む際は、その読み込み先のオブジェクトを指定する必要がある。

> rm(list = ls(all.names = TRUE))
> ls()
character(0)
> no <- 1:3
> name <- c("安野希世乃", "石見舞菜香", "和多田美咲")
> meibo <- data.frame(no, name)
> print(meibo)
no name
1 1 安野希世乃
2 2 石見舞菜香
3 3 和多田美咲
> readr::write_rds(meibo, file = "meibo.rds")
> rm(list = ls(all.names = TRUE))
> ls()
character(0)
> readr::read_rds(file = "meibo.rds")
no name
1 1 安野希世乃
2 2 石見舞菜香
3 3 和多田美咲
> ls()
character(0)
> dtf <- readr::read_rds(file = "meibo.rds")
> ls()
[1] "dtf"
> print(dtf)
no name
1 1 安野希世乃
2 2 石見舞菜香
3 3 和多田美咲

write_rds関数はsave関数やsaveRDS関数と異なり、デフォルトではファイルを圧縮処理しない。そのため、ファイルサイズは大きくなるが、その分、保存時も読み込み時も動作が早い。なお、ファイルを圧縮処理するように指定することもできる。

以下ではwrite_rds関数とread_rds関数について、適当な巨大なデータフレームを作成して、ファイルの圧縮処理するか否かで、保存・読み込み時の実行時間を比較した例。見てのとおり、圧縮処理するとファイルサイズは約半分になるが、保存時は10倍以上時間がかかることがわかる。読み込み時も、保存時ほどではないが処理が早く済むことがわかる。

> rm(list = ls(all.names = TRUE))
> len <- 20
> ch <- c(LETTERS, letters)
> n <- 10 ^ 6
> sei <- mei <- character(n)
> for (i in 1:n) sei[i] <- paste(ch[floor(runif(len, 1, length(ch) + 1))], collapse = "")
> for (i in 1:n) mei[i] <- paste(ch[floor(runif(len, 1, length(ch) + 1))], collapse = "")
> no <- 1:(n * 10)
> age <- floor(runif(n * 10, 20, 66))
> meibo <- data.frame(no, sei, mei, age)
> nrow(meibo)
[1] 10000000
> tail(meibo)
no sei mei age
9999995 9999995 hidOwZgfbrLerBCHprrj rEXTnzTjfnRHoaAYFQLk 53
9999996 9999996 KJPkdfMRQmoAsxvNXzYx DBwannCmxuEdYyfnaYTC 58
9999997 9999997 ODqATMYtqIvEzcvzfZmd QpBDgfnOUeWAkmWfzjcI 25
9999998 9999998 JsnBlbiwMdyRzGzYlOPA nJBFwQMStWHPdwEFgKMe 32
9999999 9999999 fvQMCLOULLReHDuJSrbs pSwrJDxXPYvJMeECpeoJ 33
10000000 10000000 kVmjgBweXtfoFzROlivD RaHBkUfyvlkMBeEgbTYa 36
> system.time(readr::write_rds(meibo, file = "meibo_none.rds"))
ユーザ システム 経過
1.15 0.47 2.49
> system.time(readr::write_rds(meibo, file = "meibo_none.rds"))
ユーザ システム 経過
1.06 0.27 3.32
> system.time(readr::write_rds(meibo, file = "meibo_gz.rds", compress = "gz"))
ユーザ システム 経過
18.08 0.16 21.34
> system.time(readr::write_rds(meibo, file = "meibo_gz.rds", compress = "gz"))
ユーザ システム 経過
14.11 0.23 21.75
> rm(list = ls(all.names = TRUE))
> ls()
character(0)
> file.info(dir(pattern = "*.rds"))["size"]
size
meibo_gz.rds 354125588
meibo_none.rds 680000218
> system.time(dtf <- readr::read_rds(file = "meibo_none.rds"))
ユーザ システム 経過
2.97 0.14 3.58
> system.time(dtf <- readr::read_rds(file = "meibo_none.rds"))
ユーザ システム 経過
3.48 0.32 5.09
> system.time(dtf <- readr::read_rds(file = "meibo_gz.rds"))
ユーザ システム 経過
5.98 0.03 6.72
> system.time(dtf <- readr::read_rds(file = "meibo_gz.rds"))
ユーザ システム 経過
5.92 0.07 6.74

2023年12月26日 (火)

[R]オブジェクトのクラスを調べる

Rでは、各オブジェクトのメモリへの格納方式をモードといい、これらにはさらにその格納された情報の型を持っており、その型をクラスという。通常コマンド操作をする際に意識することはないが、基礎知識として知っておくと有益。

> n <- 1:2
> s <- c("石見舞菜香", "ライスシャワー")
> b <- c(TRUE, FALSE)
> dt <- as.Date("2000-01-01")
> dtf <- data.frame(n, s)
> f <- function(x) {x ^ 2}
> class(n)
[1] "integer"
> class(s)
[1] "character"
> class(b)
[1] "logical"
> class(dt)
[1] "Date"
> class(dtf)
[1] "data.frame"
> class(f)
[1] "function"

2023年12月25日 (月)

[R]オブジェクトのモードを調べる

Rでは、各オブジェクトのメモリへの格納形式をモードという。通常コマンド操作をする際に意識することはないが、基礎知識として知っておくと有益。ベクトルのように各要素はすべて同じモードでなければならないものもあれば、リストのように異なるモードを持つものを格納できるオブジェクトもある。

> n <- 1:2
> s <- c("石見舞菜香", "ライスシャワー")
> b <- c(TRUE, FALSE)
> dt <- as.Date("2000-01-01")
> dtf <- data.frame(n, s)
> f <- function(x) {x ^ 2}
> mode(n)
[1] "numeric"
> mode(s)
[1] "character"
> mode(b)
[1] "logical"
> mode(dt)
[1] "numeric"
> mode(dtf)
[1] "list"
> mode(f)
[1] "function"

一部のモードは、typeof関数を使うともう少し詳しい情報を得ることができる。

> typeof(n)
[1] "integer"
> typeof(3.14)
[1] "double"
> typeof(dt)
[1] "double"

2023年12月21日 (木)

[R]オブジェクトを削除する

Rは代入したベクトルやリスト、定義した関数などは、明示的に削除しない限りそのままその環境に残る。再利用することができるし、逆に誤って使用してしまうこともある。その環境下に残されているオブジェクトを削除するには、rm関数を使う。

> ls()
character(0)
> n <- 1:3
> s <- c("ABC", "abc", "123")
> ls()
[1] "n" "s"
> print(s)
[1] "ABC" "abc" "123"
> rm(s)
> ls()
[1] "n"
> print(s)
エラー: オブジェクト 's' がありません

すべてのオブジェクトを削除したい倍は、listオプションにls関数の結果を与える。

> n <- 1:3
> s <- c("ABC", "abc", "123")
> ls()
[1] "n" "s"
> rm(list = ls())
> ls()
character(0)

ただし、これでは隠しオブジェクト(オブジェクト名が「.」から始まる)は削除されない。隠しオブジェクトも含めてすべて削除するには、ls関数のall.namesオプションにTRUEを与える。

> n <- 1:3
> s <- c("ABC", "abc", "123")
> d <- rnorm(4)
> ls()
[1] "d" "n" "s"
> ls(all.names = TRUE)
[1] ".Random.seed" "d" "n" "s"
> rm(list = ls())
> ls()
character(0)
> ls(all.names = TRUE)
[1] ".Random.seed"

やり直す。

> n <- 1:3
> d <- rnorm(4)
> ls(all.names = TRUE)
[1] ".Random.seed" "d" "n"
> rm(list = ls(all.names = TRUE))
> ls(all.names = TRUE)
character(0)

2023年12月17日 (日)

[R]保存されているオブジェクトを確認する

Rはオブジェクト(値を代入したベクトルやリスト、定義した関数など)は、明示的に削除しない限りそのままその環境に残る。再利用することができるし、逆に誤って使用してしまうこともある。その環境下に残されているオブジェクトを確認するには、objects関数かls関数を使う。

Rを起動した直後に実行すると、以下のようになるはず。

> objects()
character(0)

objects関数(ls関数も同様、以下同じ)は環境下に残されているオブジェクトのオブジェクト名を文字列型ベクトルで返す。起動直後は何もオブジェクトが無い(実はあるがそれは後述)ため、長さが0の文字列型ベクトルが返される。

> n <- 1:3
> s <- c("ABC", "abc", "123")
> objects()
[1] "n" "s"
> ls()
[1] "n" "s"

all.namesオプションにTRUEを与えると、隠しオブジェクト(オブジェクト名が「.」から始まる)も含めてすべて表示する。

> d <- rnorm(4)
> ls()
[1] "d" "n" "s"
> ls(all.names = TRUE)
[1] ".Random.seed" "d" "n" "s"

2018年10月31日 (水)

[R]TRUE,FALSEとT,Fの違い

TRUEとFALSEは、論理型データの定数であり予約語。一方、TとFは初期状態で定義されている論理型データの長さ1のベクトル。

TRUEとFALSEは変更することができない定数で、TとFは初期状態で存在するベクトルに過ぎないため、変更することは可能。そのため、論理式で使用するときは、TRUEとFALSEの使用を推奨する。

> TRUE; FALSE; T; F
[1] TRUE
[1] FALSE
[1] TRUE
[1] FALSE
> class(TRUE)
[1] "logical"
> class(T)
[1] "logical"
> mode(TRUE)
[1] "logical"
> mode(F)
[1] "logical"
> TRUE <- 1
TRUE <- 1 でエラー:  代入の左辺が不正 (do_set) です
> T <- 1
> TRUE; FALSE; T; F
[1] TRUE
[1] FALSE
[1] 1
[1] FALSE
> class(T)
[1] "numeric"

2014年3月 7日 (金)

[R]モードについて

Rのすべてのオブジェクトはモードを持つ。モードとはメモリへの格納方法を示した物理的な型のこと。

各オブジェクトのモードを調べるにはmode関数を使う。

> mode(1.2)
[1] "numeric"
> mode("A")
[1] "character"
> mode(as.Date("2013-12-31"))
[1] "numeric"

Dateオブジェクトのモードはnumericであることに注意。