« 2024年1月 | トップページ | 2024年3月 »

2024年2月29日 (木)

[C#]カレントディレクトリを得る、設定する

設定をするには、DirectoryクラスのSetCurrentDirectoryメソッドか、EnvironmentクラスのCurrentDirectoryプロパティに代入する。得るには、DirectoryクラスのGetCurrentDirectoryメソッドか、EnvironmentクラスのCurrentDirectoryプロパティを参照する。

> System.IO.Directory.SetCurrentDirectory(@"C:\Windows\System32");
> Console.WriteLine(System.IO.Directory.GetCurrentDirectory());
C:\Windows\System32
> System.Environment.CurrentDirectory = @"C:\Windows";
> Console.WriteLine(System.Environment.CurrentDirectory);
C:\Windows

2024年2月28日 (水)

[R]SQLiteのデータベースに含まれるテーブルを一覧表示する

dbListTablesを使う。引数には接続を指定する。以下は、2つのテーブルが含まれたあらかじめ作成してあるデータベースで一覧表示させた例。dbListFields関数は、指定したテーブルのすべてのフィールド名(列名)を返す。

> con <- dbConnect(SQLite(), "princess.sqlite")
> dbListTables(con)
[1] "macross_delta" "umamusume"
> dbListFields(con, "macross_delta")
[1] "no" "mei" "sei" "fname" "lname" "seiyu"
> dbListFields(con, "umamusume")
[1] "no" "name" "seiyu"
> dbDisconnect(con)

2024年2月27日 (火)

[R]SQLiteのデータベースにテーブルを作成する

dbWriteTable関数にデータフレームを指定すると、そのデータフレームの構造のテーブルが作成される。以下は、あらかじめ作成したデータフレームdtfを書き込んでテーブルを作成した例。dbExistsTable関数は、指定した接続先に指定したテーブルがあるか否かを判定する関数。テーブルの中身を読み込むにはdbReadTable関数を使う。テーブル内のすべてのフィールド名(列名)を得るにはdbListFileds関数を使う。

> library(RSQLite)
> con <- dbConnect(SQLite(), "princess.sqlite")
> dbExistsTable(con, "macross_delta")
[1] FALSE
> print(dtf)
no mei sei fname lname seiyu
1 1 カナメ バッカニア Kaname Buccaneer 安野希世乃
2 2 フレイア ヴィオン Freyja Wion 鈴木みのり
3 3 美雲 ギンヌメール Mikumo Guynemer 小清水亜美
4 4 マキナ 中島 Makina Nakajima 西田望見
5 5 レイナ プラウラー Reina Prowler 東山奈央
> dbWriteTable(con, "macross_delta", dtf)
> dbExistsTable(con, "macross_delta")
[1] TRUE

書き込んだテーブルを読み出してみる。

> dtf2 <- dbReadTable(con, "macross_delta")
> print(dtf2)
no mei sei fname lname seiyu
1 1 カナメ バッカニア Kaname Buccaneer 安野希世乃
2 2 フレイア ヴィオン Freyja Wion 鈴木みのり
3 3 美雲 ギンヌメール Mikumo Guynemer 小清水亜美
4 4 マキナ 中島 Makina Nakajima 西田望見
5 5 レイナ プラウラー Reina Prowler 東山奈央
> dbListFields(con, "macross_delta")
[1] "no" "mei" "sei" "fname" "lname" "seiyu"
> dbDisconnect(con)

2024年2月26日 (月)

[R]SQLiteのデータベースを作成する

パッケージRSQLiteにおいてデータベースはデータベースのファイルそのものであり、dbConnect関数でファイルを指定して接続するとファイルが存在すれば自動的にファイルが作成され、それがデータベースになる。ファイルが存在すれば、既存のデータベースに接続することになる。

以下は、存在しないprincess.sqliteというファイルを指定して接続を行い、umamusumeというテーブルを書き込んで接続を閉じた例。最後に接続を閉じることを忘れないこと(閉じないとファイルに処理した内容が書き込まれない)。

> file.exists("princess.sqlite")
[1] FALSE
> library(RSQLite)
> con <- dbConnect(SQLite(), "princess.sqlite")
> dtf <- data.frame(
+ no = c(30, 45, 58),
+ name = c("ライスシャワー", "スーパークリーク", "メイショウドトウ"),
+ seiyu = c("石見舞菜香", "優木かな", "和多田美咲"))
> print(dtf)
no name seiyu
1 30 ライスシャワー 石見舞菜香
2 45 スーパークリーク 優木かな
3 58 メイショウドトウ 和多田美咲
> dbWriteTable(con, "umamusume", dtf)
> dbDisconnect(con)
> file.exists("princess.sqlite")
[1] TRUE
> file.info("princess.sqlite")$size
[1] 8192
> file.size("princess.sqlite")
[1] 8192

閉じたデータベースを改めて接続して読み込んでみる。

> con <- dbConnect(SQLite(), "princess.sqlite")
> dbGetQuery(con, "select * from umamusume")
no name seiyu
1 30 ライスシャワー 石見舞菜香
2 45 スーパークリーク 優木かな
3 58 メイショウドトウ 和多田美咲
> dtf <- dbGetQuery(con, "select * from umamusume")
> print(dtf)
no name seiyu
1 30 ライスシャワー 石見舞菜香
2 45 スーパークリーク 優木かな
3 58 メイショウドトウ 和多田美咲
> dbDisconnect(con)

2024年2月25日 (日)

[R]SQLiteを使う

データベース管理システムの一つであるSQLiteをRで使うには、RSQLiteパッケージを使えばよい。

> options(repos = "https://ftp.yz.yamagata-u.ac.jp/pub/cran/")
> install.packages("RSQLite")
パッケージを ‘C:/Users/○○○/AppData/Local/R/win-library/4.3’ 中にインストールします
(‘lib’ が指定されていないため)
依存対象 (dependency) ‘DBI’ もインストールします
(表示省略)

2024年2月23日 (金)

[R]tibbleを任意の列のみのtibbleに変換する

tidyverse(dplyr)パッケージのselect関数を使う。以下、あらかじめ用意してあるtibbleを使用した動作例。列名を指定するとその列だけを含むtibble(ベクトルではない!)に変換する。:(コロン)を使うとそれを両端としたその範囲の列すべてを抜き出す。接頭辞として-(マイナス)を付けるとその列を含まないという意味になる。列の指定には列名と番号(1~)が使える。等号(=)を使うことで列名を変えて取り出すこともできる。

> library(tidyverse)
> tib %>% as.data.frame()
no name prizemoney seiyu dummydate
1 8 ウオッカ 13.0487 大橋彩香 2031-02-03
2 30 ライスシャワー 6.6686 石見舞菜香 2032-11-12
3 45 スーパークリーク 5.5610 優木かな 2033-11-12
4 58 メイショウドトウ 9.2133 和多田美咲 2033-12-31
> tib %>% select(name, seiyu) %>% as.data.frame()
name seiyu
1 ウオッカ 大橋彩香
2 ライスシャワー 石見舞菜香
3 スーパークリーク 優木かな
4 メイショウドトウ 和多田美咲
> tib %>% select(name:seiyu) %>% as.data.frame()
name prizemoney seiyu
1 ウオッカ 13.0487 大橋彩香
2 ライスシャワー 6.6686 石見舞菜香
3 スーパークリーク 5.5610 優木かな
4 メイショウドトウ 9.2133 和多田美咲
> tib %>% select(2, 4) %>% as.data.frame()
name seiyu
1 ウオッカ 大橋彩香
2 ライスシャワー 石見舞菜香
3 スーパークリーク 優木かな
4 メイショウドトウ 和多田美咲
> tib %>% select(2:4) %>% as.data.frame()
name prizemoney seiyu
1 ウオッカ 13.0487 大橋彩香
2 ライスシャワー 6.6686 石見舞菜香
3 スーパークリーク 5.5610 優木かな
4 メイショウドトウ 9.2133 和多田美咲
> tib %>% select(-(no:prizemoney), -dummydate) %>% as.data.frame()
seiyu
1 大橋彩香
2 石見舞菜香
3 優木かな
4 和多田美咲
> tib %>% select(-(1:3), -5) %>% as.data.frame()
seiyu
1 大橋彩香
2 石見舞菜香
3 優木かな
4 和多田美咲
> tib %>% select(name, cv = seiyu) %>% as.data.frame()
name cv
1 ウオッカ 大橋彩香
2 ライスシャワー 石見舞菜香
3 スーパークリーク 優木かな
4 メイショウドトウ 和多田美咲

2024年2月22日 (木)

[R]ヌル(0x00)を含むテキストファイルを高速に読み込む

始めにヌルを含む巨大なテキストファイルを作成する。以下は文字コードがUTF-8の環境のため(3×5+2)×2×10^7=340,000,000バイト(約324MB)のテキストファイルを作成している。ファイルの行数は10^7=10,000,000行。それぞれの行は苗字と名前の間にヌル(0x00)が挟まれている。

> Sys.getlocale()
[1] "LC_COLLATE=Japanese_Japan.utf8;LC_CTYPE=Japanese_Japan.utf8;LC_MONETARY=Japanese_Japan.utf8;LC_NUMERIC=C;LC_TIME=Japanese_Japan.utf8"
> ra1 <- unlist(iconv("石見", toRaw = TRUE))
> ra2 <- unlist(iconv("舞菜香", toRaw = TRUE))
> ra3 <- unlist(iconv("和多田", toRaw = TRUE))
> ra4 <- unlist(iconv("美咲", toRaw = TRUE))
> ra <- c(ra1, as.raw(0), ra2, as.raw(0x0a), ra3, as.raw(0), ra4, as.raw(0x0a))
> writeBin(rep(ra, 10 ^ 7), "temp.txt")
> file.info(dir(patter = "temp\\.txt"))["size"]
size
temp.txt 3.4e+08

scan関数を使用して読み込む場合は、skipNulオプションにTRUEを指定しないとうまく読み込むことができない。

> lns <- scan("temp.txt", what = character(), sep = "\n", quiet = TRUE)
警告メッセージ:
scan("temp.txt", what = character(), sep = "\n", quiet = TRUE) で:
入力文字列の中に nul が埋め込まれています
> length(lns)
[1] 20000000
> lns[1:3]
[1] "石見" "和多田" "石見"
> lns <- scan("temp.txt", what = character(), sep = "\n", quiet = TRUE, skipNul = TRUE)
> length(lns)
[1] 20000000
> lns[1:3]
[1] "石見舞菜香" "和多田美咲" "石見舞菜香"

read.table関数を使用して読み込む場合も、skipNulオプションにTRUEを指定しないとうまく読み込むことができない。

> dtf <- read.table("temp.txt", header = FALSE, sep = "\n")
警告メッセージ:
1: read.table("temp.txt", header = FALSE, sep = "\n") で:
line 1 appears to contain embedded nulls
2: read.table("temp.txt", header = FALSE, sep = "\n") で:
line 2 appears to contain embedded nulls
(表示省略)
入力文字列の中に nul が埋め込まれています
> nrow(dtf)
[1] 20000000
> head(dtf, 3)
V1
1 石見
2 和多田
3 石見
> dtf <- read.table("temp.txt", header = FALSE, sep = "\n", skipNul = TRUE)
> nrow(dtf)
[1] 20000000
> head(dtf, 3)
V1
1 石見舞菜香
2 和多田美咲
3 石見舞菜香

それぞれの関数で読み込みに要する時間を計測してみる。

> system.time(
+ scan("temp.txt", what = character(), sep = "\n", quiet = TRUE, skipNul = TRUE)
+ )
ユーザ システム 経過
3.06 0.14 3.86
> system.time(
+ scan("temp.txt", what = character(), sep = "\n", quiet = TRUE, skipNul = TRUE)
+ )
ユーザ システム 経過
3.35 0.14 3.89
> system.time(
+ read.table("temp.txt", header = FALSE, sep = "\n", skipNul = TRUE)
+ )
ユーザ システム 経過
3.06 0.09 4.03
> system.time(
+ read.table("temp.txt", header = FALSE, sep = "\n", skipNul = TRUE)
+ )
ユーザ システム 経過
2.92 0.20 4.06

scan関数の方が若干早い。なお、単純にテキストファイルを読み込むだけであればreadrパッケージのfread関数やread_lines関数のほうが高速に動作するが、以下の例のとおりにヌルを含むとうまく動作をしない。これを制御するオプションは無いようだ。

> library(readr)
> fread("temp.txt", sep = "\n")
fread("temp.txt", sep = "\n") でエラー:
文字列の中に nul が埋め込まれています: '石見\0舞菜香'
追加情報: 警告メッセージ:
fread("temp.txt", sep = "\n") で:
Previous fread() session was not cleaned up properly. Cleaned up ok at the beginning of this fread() call.
> read_lines("temp.txt", progress = FALSE)
character(0)

2024年2月21日 (水)

[R]tibbleの指定した列から重複を取り除いてその列だけを返す

distinct関数を使う。引数に指定した列から重複を取り除いてその列だけを返す。2つ以上同時に指定もできる。

> tib %>% as.data.frame()
title seiyu
1 ウマ娘 大橋彩香
2 ウマ娘 大橋彩香
3 ウマ娘 石見舞菜香
4 ライザのアトリエ2 石見舞菜香
5 推しの子 石見舞菜香
6 ウマ娘 和多田美咲
> tib %>% distinct(title) %>% as.data.frame()
title
1 ウマ娘
2 ライザのアトリエ2
3 推しの子
> tib %>% distinct(seiyu) %>% as.data.frame()
seiyu
1 大橋彩香
2 石見舞菜香
3 和多田美咲
> tib %>% distinct(title, seiyu) %>% as.data.frame()
title seiyu
1 ウマ娘 大橋彩香
2 ウマ娘 石見舞菜香
3 ライザのアトリエ2 石見舞菜香
4 推しの子 石見舞菜香
5 ウマ娘 和多田美咲

2024年2月20日 (火)

[R]リストの各要素からインデックスを指定してまとめて値を抜き出す

sapply関数に「[[」を指定して使う。以下は、要素がすべてベクトルのリストについて、各要素の1~3番目の要素を抜き出した例。3番目の要素は要素が二つしかないため、3番目の要素を抜き出そうとするとエラーが発生する。lapply関数を使えば、戻り値はリストになる。参考に、最初にリストの各要素の要素数を得ている。

> chara <- c("ライスシャワー", "メイショウドトウ", "フィー", "黒川あかね")
> sakuhin <- c("ウマ娘", "ライザのアトリエ2", "推しの子")
> seiyu <- c("石見舞菜香", "和多田美咲")
> lis <- list(chara, sakuhin, seiyu)
> print(lis)
[[1]]
[1] "ライスシャワー" "メイショウドトウ" "フィー" "黒川あかね"
[[2]]
[1] "ウマ娘" "ライザのアトリエ2" "推しの子"
[[3]]
[1] "石見舞菜香" "和多田美咲"
> sapply(lis, length)
[1] 4 3 2
> sapply(lis, "[[", 1)
[1] "ライスシャワー" "ウマ娘" "石見舞菜香"
> sapply(lis, "[[", 2)
[1] "メイショウドトウ" "ライザのアトリエ2" "和多田美咲"
> sapply(lis, "[[", 3)
FUN(X[[i]], ...) でエラー: 添え字が許される範囲外です
> lapply(lis, "[[", 1)
[[1]]
[1] "ライスシャワー"
[[2]]
[1] "ウマ娘"
[[3]]
[1] "石見舞菜香"
> lapply(lis, "[[", 2)
[[1]]
[1] "メイショウドトウ"
[[2]]
[1] "ライザのアトリエ2"
[[3]]
[1] "和多田美咲"
> lapply(lis, "[[", 3)
FUN(X[[i]], ...) でエラー: 添え字が許される範囲外です

2024年2月19日 (月)

[R]リストの要素を削除する

削除したい要素にNULLを代入する。以下の例のとおり、ベクトルと異なりリストの要素にNULLを代入すると、その要素は消去され順番が詰まり、リストの要素数が一つ減る。

> chara <- c("ライスシャワー", "メイショウドトウ", "フィー", "黒川あかね")
> sakuhin <- c("ウマ娘", "ライザのアトリエ2", "推しの子")
> seiyu <- c("石見舞菜香", "和多田美咲")
> lis <- list(chara, sakuhin, seiyu)
> print(lis)
[[1]]
[1] "ライスシャワー" "メイショウドトウ" "フィー"
[4] "黒川あかね"
[[2]]
[1] "ウマ娘" "ライザのアトリエ2" "推しの子"
[[3]]
[1] "石見舞菜香" "和多田美咲"
> lis[2] <- NULL
> print(lis)
[[1]]
[1] "ライスシャワー" "メイショウドトウ" "フィー"
[4] "黒川あかね"
[[2]]
[1] "石見舞菜香" "和多田美咲"

2024年2月17日 (土)

[R]リストから要素を取り出す

[ ]演算子と[[ ]]演算子を使いそれぞれインデックスを与えると要素を取り出すことができる。戻り値は[ ]演算子はリスト、[[ ]]演算子はベクトルになる。

> chara <- c("ライスシャワー", "メイショウドトウ", "フィー", "黒川あかね")
> sakuhin <- c("ウマ娘", "ライザのアトリエ2", "推しの子")
> seiyu <- c("石見舞菜香", "和多田美咲")
> lis <- list(chara, sakuhin, seiyu)
> print(lis)
[[1]]
[1] "ライスシャワー" "メイショウドトウ" "フィー"
[4] "黒川あかね"
[[2]]
[1] "ウマ娘" "ライザのアトリエ2" "推しの子"
[[3]]
[1] "石見舞菜香" "和多田美咲"

[ ]演算子は指定の要素を単純にリストで返す。複数のインデックスで指定することも可能。

> lis[2]
[[1]]
[1] "ウマ娘" "ライザのアトリエ2" "推しの子"
> lis[2:3]
[[1]]
[1] "ウマ娘" "ライザのアトリエ2" "推しの子"
[[2]]
[1] "石見舞菜香" "和多田美咲"

[[ ]]演算子は指定の要素をベクトルで返す。複数のインデックスで指定することはできず、以下の例のとおりc(○,×)と指定すると、要素がベクトルであれば、リストの○番目の要素の、その要素の×番目のベクトルの要素を返す。

> lis[[2]]
[1] "ウマ娘" "ライザのアトリエ2" "推しの子"
> lis[[c(2, 1)]]
[1] "ウマ娘"
> lis[[c(3, 2)]]
[1] "和多田美咲"

リストの複数の要素をベクトルでまとめて返したい場合は、unlist関数を利用する。

> unlist(lis[2:3])
[1] "ウマ娘" "ライザのアトリエ2" "推しの子"
[4] "石見舞菜香" "和多田美咲"

2024年2月16日 (金)

[R]strsplit関数とstr_split関数の動作の違い

strsplit関数とstringrパッケージのstr_split関数は、どちらも正規表現を使用して文字列を分割する関数だが、動作が若干異なる。以下の例のとおり、分割に指定した文字が文字列の最後に存在すると、strsplit関数はその最後の分割された文字列("")を返すことを省略するので注意。どちらも戻り値はリストである。

> s <- character(5)
> s[1] <- "//ウマ娘/アグネスデジタル/鈴木みのり"
> s[2] <- "/ウマ娘/ライスシャワー/石見舞菜香"
> s[3] <- "ウマ娘/メイショウドトウ/和多田美咲"
> s[4] <- "ウマ娘/サクラチヨノオー/野口瑠璃子/"
> s[5] <- "ウマ娘/メジロアルダン/会沢紗弥//"
> strsplit(s, "/")
[[1]]
[1] "" "" "ウマ娘" "アグネスデジタル" "鈴木みのり"
[[2]]
[1] "" "ウマ娘" "ライスシャワー" "石見舞菜香"
[[3]]
[1] "ウマ娘" "メイショウドトウ" "和多田美咲"
[[4]]
[1] "ウマ娘" "サクラチヨノオー" "野口瑠璃子"
[[5]]
[1] "ウマ娘" "メジロアルダン" "会沢紗弥" ""
> stringr::str_split(s, "/")
[[1]]
[1] "" "" "ウマ娘" "アグネスデジタル" "鈴木みのり"
[[2]]
[1] "" "ウマ娘" "ライスシャワー" "石見舞菜香"
[[3]]
[1] "ウマ娘" "メイショウドトウ" "和多田美咲"
[[4]]
[1] "ウマ娘" "サクラチヨノオー" "野口瑠璃子" ""
[[5]]
[1] "ウマ娘" "メジロアルダン" "会沢紗弥" "" ""

どちらの関数も、分割する文字列の指定に正規表現を使うことができる。

> s <- character(3)
> s[1] <- "ウオッカ/大橋彩香"
> s[2] <- "ゴールドシチー//香坂さき"
> s[3] <- "スーパークリーク///優木かな"
> str_split(s, "/+")
[[1]]
[1] "ウオッカ" "大橋彩香"
[[2]]
[1] "ゴールドシチー" "香坂さき"
[[3]]
[1] "スーパークリーク" "優木かな"
> strsplit(s, "/+")
[[1]]
[1] "ウオッカ" "大橋彩香"
[[2]]
[1] "ゴールドシチー" "香坂さき"
[[3]]
[1] "スーパークリーク" "優木かな"

str_split_1関数は機能はほぼ同じで戻り値がベクトルになる関数。ただし、要素数が1つのベクトルしか扱うことができない。

> str_split_1(s, "/+")
Error in `str_split_1()`:
! `string` must be a single string, not a character vector.
Run `rlang::last_trace()` to see where the error occurred.
> str_split_1(s[1], "/+")
[1] "ウオッカ" "大橋彩香"

2024年2月15日 (木)

[R]リストの各要素に一括で関数を適用する

lapply関数かsapply関数を使う。この2つの関数の処理は同じで、戻り値が前者はリスト、後者はベクトル(各要素の戻り値が複数になる場合はリスト)と異なるだけ。以下は、3つの英文を空白で分割し、3つの文の分割した各要素数とそれらの要素(文字列)の長さを調べた例。

> s <- character(3)
> s[1] <- "Iwami Manaka played the part of Rice Shower."
> s[2] <- "She's very good in the part."
> s[3] <- "She's a brilliant actress."
> words <- strsplit(s, "\\s+")
> print(words)
[[1]]
[1] "Iwami" "Manaka" "played" "the" "part" "of" "Rice" "Shower."
[[2]]
[1] "She's" "very" "good" "in" "the" "part."
[[3]]
[1] "She's" "a" "brilliant" "actress."
> lapply(words, length)
[[1]]
[1] 8
[[2]]
[1] 6
[[3]]
[1] 4
> sapply(words, length)
[1] 8 6 4
> lapply(words, nchar)
[[1]]
[1] 5 6 6 3 4 2 4 7
[[2]]
[1] 5 4 4 2 3 5
[[3]]
[1] 5 1 9 8
> sapply(words, nchar)
[[1]]
[1] 5 6 6 3 4 2 4 7
[[2]]
[1] 5 4 4 2 3 5
[[3]]
[1] 5 1 9 8

2024年2月14日 (水)

[C#]コマンドラインでコンパイルするときのソースファイルの文字コードの指定

-codepageオプションを使う。以下の2行からなるソースファイルをそれぞれWriteLineSjis.cs(文字コードはShift_JISにする)、WriteLineUtf8.cs(同UTF-8)と保存をして、それぞれコードページ識別子である932(Shift_JISのこと)と65001(UTF-8のこと)を指定してコンパイルおよび実行してみる。

using System;
Console.WriteLine("メイショウドトウ役の和多田美咲さんかわいい");

Shift_JISで保存をしたファイルをコンパイルして実行する。

>csc -codepage:932 WriteLineSjis.cs
Microsoft (R) Visual C# Compiler バージョン 4.4.0-6.22608.27 (af1e46ad)
Copyright (C) Microsoft Corporation. All rights reserved.
>WriteLineSjis.exe
メイショウドトウ役の和多田美咲さんかわいい
>csc -codepage:65001 WriteLineSjis.cs
Microsoft (R) Visual C# Compiler バージョン 4.4.0-6.22608.27 (af1e46ad)
Copyright (C) Microsoft Corporation. All rights reserved.
>WriteLineSjis.exe
???C?V???E?h?g?E???a???c???炳??????

UTF-8で保存をしたファイルをコンパイルして実行する。

>csc -codepage:65001 WriteLineUtf8.cs
Microsoft (R) Visual C# Compiler バージョン 4.4.0-6.22608.27 (af1e46ad)
Copyright (C) Microsoft Corporation. All rights reserved.
>WriteLineUtf8.exe
メイショウドトウ役の和多田美咲さんかわいい
>csc -codepage:932 WriteLineUtf8.cs
Microsoft (R) Visual C# Compiler バージョン 4.4.0-6.22608.27 (af1e46ad)
Copyright (C) Microsoft Corporation. All rights reserved.
>WriteLineUtf8.exe
繝。繧、繧キ繝ァ繧ヲ繝峨ヨ繧ヲ蠖ケ縺ョ蜥悟、夂伐鄒主調縺輔s縺九o縺・>

オプションに指定したコードページとソースコードの文字コードが合っていなくてもコンパイルはできるが、文字コードは指定どおりに解釈されてコンパイルされてしまうことに注意。

コードページ識別子の一覧は以下を参照のこと。
https://learn.microsoft.com/ja-jp/windows/win32/intl/code-page-identifiers

2024年2月13日 (火)

[R]特定の列の値を基準にして2つのtibbleが結合できるか否か確認する

tidyverse(dplyr)パッケージのsemi_join関数、anti_join関数を使う。基準とする列の指定にはjoin_by関数を使う。以下は、次の2つのtibbleを指定の列(以下の例ではcvとid)の値を基準にして結合できるか否か確認した例。簡潔な表示にするため、表示はすべてデータフレームで行っている。

> chara %>% as.data.frame()
nama title no cv
1 ライスシャワー ウマ娘 30 miwami01
2 スーパークリーク ウマ娘 45 kyuki01
3 メイショウドトウ ウマ娘 58 mwatada01
4 ライザ ライザのアトリエ2 1 ynoguchi01
5 フィー ライザのアトリエ2 2 mwatada01
6 黒川あかね 推しの子 6 miwami01
> seiyu %>% as.data.frame()
id name
1 miwami01 石見舞菜香
2 kyuki01 優木かな
3 mwatada01 和多田美咲
4 machico01 Machico

semi_join関数は、右側に指定の列の値が一致する行がある左側の行を返す。inner_join関数と動作は似ているが、semi_join関数は、結合はせずに結合が可能な左側の行だけを返す。

> chara %>% inner_join(seiyu, by = join_by(cv == id)) %>% as.data.frame()
nama title no cv name
1 ライスシャワー ウマ娘 30 miwami01 石見舞菜香
2 スーパークリーク ウマ娘 45 kyuki01 優木かな
3 メイショウドトウ ウマ娘 58 mwatada01 和多田美咲
4 フィー ライザのアトリエ2 2 mwatada01 和多田美咲
5 黒川あかね 推しの子 6 miwami01 石見舞菜香
> chara %>% semi_join(seiyu, by = join_by(cv == id)) %>% as.data.frame()
nama title no cv
1 ライスシャワー ウマ娘 30 miwami01
2 スーパークリーク ウマ娘 45 kyuki01
3 メイショウドトウ ウマ娘 58 mwatada01
4 フィー ライザのアトリエ2 2 mwatada01
5 黒川あかね 推しの子 6 miwami01

anti_join関数は、右側に指定の列の値が一致する行がない左側の行を返す。left_join関数では無理矢理結合され列にNAが代入された行(以下の4行目)だけが返されるが、anti_join関数は結合はせずに左側の行だけを返す。

> chara %>% left_join(seiyu, by = join_by(cv == id)) %>% as.data.frame()
nama title no cv name
1 ライスシャワー ウマ娘 30 miwami01 石見舞菜香
2 スーパークリーク ウマ娘 45 kyuki01 優木かな
3 メイショウドトウ ウマ娘 58 mwatada01 和多田美咲
4 ライザ ライザのアトリエ2 1 ynoguchi01 <NA>
5 フィー ライザのアトリエ2 2 mwatada01 和多田美咲
6 黒川あかね 推しの子 6 miwami01 石見舞菜香
> chara %>% anti_join(seiyu, by = join_by(cv == id)) %>% as.data.frame()
nama title no cv
1 ライザ ライザのアトリエ2 1 ynoguchi01

2024年2月12日 (月)

[R]指定の列の値を基準にして2つのtibbleを結合する

tidyverse(dplyr)パッケージのleft_join関数、right_join関数、inner_join関数、full_join関数を使う。基準とする列の指定にはjoin_by関数を使う。以下は、次の2つのtibbleを指定の列(以下の例ではcvとid)の値を基準にして結合した例。簡潔な表示にするため、表示はすべてデータフレームで行っている。

> library(tidyverse)
> chara %>% as.data.frame()
nama title no cv
1 ライスシャワー ウマ娘 30 miwami01
2 スーパークリーク ウマ娘 45 kyuki01
3 メイショウドトウ ウマ娘 58 mwatada01
4 ライザ ライザのアトリエ2 1 ynoguchi01
5 フィー ライザのアトリエ2 2 mwatada01
6 黒川あかね 推しの子 6 miwami01
> seiyu %>% as.data.frame()
id name
1 miwami01 石見舞菜香
2 kyuki01 優木かな
3 mwatada01 和多田美咲
4 machico01 Machico

left_join関数は、左側のtibbleの行はすべて採用され、右側のtibbleは指定の列が一致した行だけが結合される。一致の無かった左側の行の連結により作成される列にはNAが挿入される(以下の4行目)。

> chara %>% left_join(seiyu, by = join_by(cv == id)) %>% as.data.frame()
nama title no cv name
1 ライスシャワー ウマ娘 30 miwami01 石見舞菜香
2 スーパークリーク ウマ娘 45 kyuki01 優木かな
3 メイショウドトウ ウマ娘 58 mwatada01 和多田美咲
4 ライザ ライザのアトリエ2 1 ynoguchi01 <NA>
5 フィー ライザのアトリエ2 2 mwatada01 和多田美咲
6 黒川あかね 推しの子 6 miwami01 石見舞菜香

right_join関数は、右側のtibbleの列はすべて採用され、左側のtibbleは指定の列が一致した行だけが結合される。一致の無かった右側の行の連結により作成される列にはNAが挿入される(以下の6行目)。

> chara %>% right_join(seiyu, by = join_by(cv == id)) %>% as.data.frame()
nama title no cv name
1 ライスシャワー ウマ娘 30 miwami01 石見舞菜香
2 スーパークリーク ウマ娘 45 kyuki01 優木かな
3 メイショウドトウ ウマ娘 58 mwatada01 和多田美咲
4 フィー ライザのアトリエ2 2 mwatada01 和多田美咲
5 黒川あかね 推しの子 6 miwami01 石見舞菜香
6 <NA> <NA> NA machico01 Machico

inner_join関数は、指定の列の値が一致した組み合わせのみがすべて結合される。

> chara %>% inner_join(seiyu, by = join_by(cv == id)) %>% as.data.frame()
nama title no cv name
1 ライスシャワー ウマ娘 30 miwami01 石見舞菜香
2 スーパークリーク ウマ娘 45 kyuki01 優木かな
3 メイショウドトウ ウマ娘 58 mwatada01 和多田美咲
4 フィー ライザのアトリエ2 2 mwatada01 和多田美咲
5 黒川あかね 推しの子 6 miwami01 石見舞菜香

full_join関数は、左側のtibbleの行はすべて採用され、右側のtibbleの行もすべて採用される。指定の列が一致したものは一致したもの同士で結合し、結合できない行の空いた列にはNAが挿入されて結合される(以下の4行目と7行目)。

> chara %>% full_join(seiyu, by = join_by(cv == id)) %>% as.data.frame()
nama title no cv name
1 ライスシャワー ウマ娘 30 miwami01 石見舞菜香
2 スーパークリーク ウマ娘 45 kyuki01 優木かな
3 メイショウドトウ ウマ娘 58 mwatada01 和多田美咲
4 ライザ ライザのアトリエ2 1 ynoguchi01 <NA>
5 フィー ライザのアトリエ2 2 mwatada01 和多田美咲
6 黒川あかね 推しの子 6 miwami01 石見舞菜香
7 <NA> <NA> NA machico01 Machico

2024年2月11日 (日)

[R]leafletを使用して地図上にポップアップを表示する

leafletパッケージのaddPopups関数を使う。popupオプションに指定した文字列が表示される。



> library(leaflet)
> library(magrittr)
> lng0 <- 139.962
> lat0 <- 35.725
> lngs <- rnorm(5, lng0, 2.e-3)
> lats <- rnorm(5, lat0, 2.e-3)
> name <- c("高柳知葉", "大橋彩香", "石見舞菜香", "香坂さき", "和多田美咲")
> lf0 <- leaflet() %>% addTiles() %>% setView(lng = lng0, lat = lat0, zoom = 16)
> lf <- lf0 %>% addPopups(lng = lngs[1:3], lat = lats[1:3], popup = name[1:3])
> lf %>% addPopups(lng = lngs[4:5], lat = lats[4:5], popup = name[4:5])


R_leaflet_popup

2024年2月 7日 (水)

[R]leafletを使用して地図上にマーカーを表示する

leafletパッケージのaddMarkers関数を使う。labelオプションに文字列を指定すると、マーカーにマウスカーソルを重ねたときにその文字列が表示される。



> library(leaflet)
> library(magrittr)
> lng0 <- 139.962
> lat0 <- 35.725
> lngs <- rnorm(5, lng0, 2.e-3)
> lats <- rnorm(5, lat0, 2.e-3)
> name <- c("高柳知葉", "大橋彩香", "石見舞菜香", "香坂さき", "和多田美咲")
> lf <- leaflet() %>% addTiles() %>% setView(lng = lng0, lat = lat0, zoom = 16)
> lf %>% addMarkers(lng = lngs, lat = lats, label = name)


R_leaflet_marker

2024年2月 6日 (火)

[R]leafletを使用して表示場所とズームレベルを指定して地理院地図を表示する

leafletパッケージのaddTiles関数とsetView関数を組み合わせて使う。addTiles関数の第1引数に地理院地図のタイル(地理院タイル)を指定する。



> library(leaflet)
> library(magrittr)
> tile <- 'https://cyberjapandata.gsi.go.jp/xyz/std/{z}/{x}/{y}.png'
> att <- '© 国土地理院'
> lf <- leaflet() %>% addTiles(tile, attribution = att)
> lf %>% setView(lng = 139.962, lat = 35.725, zoom = 16)


R_leaflet_gsimaps

2024年2月 5日 (月)

[R]TSV形式でテキストファイルに高速で書き込む

readrパッケージのwrite_tsv関数を使う。以下は500万行からなるデータフレームをwrite.tableとwrite_tsv関数でそれぞれTSV形式のテキストファイルに3回ずつ出力し、それに要した時間を計測した例。write_tsv関数のほうが10倍以上速いことがわかる。

> library(readr)
> n <- 5 * 10 ^ 6
> no <- 1:n
> s <- c("大橋彩香", "石見舞菜香", "優木かな", "和多田美咲")
> name <- sample(s, n, replace = TRUE)
> shoe_size <- round(rnorm(n, 23.5, 1), 1)
> dtf <- data.frame(no, name, shoe_size)
> head(dtf, 6)
no name shoe_size
1 1 石見舞菜香 24.3
2 2 石見舞菜香 23.2
3 3 和多田美咲 23.6
4 4 大橋彩香 24.8
5 5 石見舞菜香 25.1
6 6 優木かな 24.7
> system.time(
+ write.table(dtf, "temp.tsv", sep = "\t", quote = FALSE, row.names = FALSE)
+ )
ユーザ システム 経過
9.86 0.06 12.78
> system.time(
+ write.table(dtf, "temp.tsv", sep = "\t", quote = FALSE, row.names = FALSE)
+ )
ユーザ システム 経過
9.43 0.14 12.94
> system.time(
+ write.table(dtf, "temp.tsv", sep = "\t", quote = FALSE, row.names = FALSE)
+ )
ユーザ システム 経過
9.55 0.09 13.06
> system.time(write_tsv(dtf, "temp.tsv", eol = "\r\n", progress = FALSE))
ユーザ システム 経過
0.60 0.05 0.16
> system.time(write_tsv(dtf, "temp.tsv", eol = "\r\n", progress = FALSE))
ユーザ システム 経過
0.62 0.10 0.16
> system.time(write_tsv(dtf, "temp.tsv", eol = "\r\n", progress = FALSE))
ユーザ システム 経過
0.92 0.07 0.84

2024年2月 4日 (日)

[R]正規表現を使用してファイル名を表す文字列から拡張子を抜き出す

1つ目の例では、最後の拡張子を1つだけ抜き出している。2つ目の例では、1つ以上の拡張子のすべてを抜き出している。

> s <- c("カナメ.バッカニア.txt", "フレイア.ヴィオン.txt")
> gsub("^.+\\.", "", s)
[1] "txt" "txt"
> gsub("^[^\\.]+\\.", "", s)
[1] "バッカニア.txt" "ヴィオン.txt"

2024年2月 3日 (土)

[R]tibbleの別の列の値を条件に使用して指定の列の値を変更する

mutate関数とcase_when関数を組み合わせて使う。以下は、次のtibbleについてそのtibbleの別の列の値からそれぞれcv列に値を代入した例。

> library(tidyverse)
> tib %>% as.data.frame()
title no chara cv
1 ウマ娘 30 ライスシャワー NA
2 ウマ娘 45 スーパークリーク NA
3 ウマ娘 58 メイショウドトウ NA
4 ライザのアトリエ2 1 ライザ NA
5 ライザのアトリエ2 2 フィー NA
6 推しの子 6 黒川あかね NA

case_when関数には条件ごとにコンマで区切って「条件式 ~ 代入する値」と指定する。指定した順に評価されて代入される。条件に一致しないものは何もしない。

> tib %>% mutate(cv = case_when(
+ title == "ウマ娘" & chara == "ライスシャワー" ~ "石見舞菜香",
+ chara == "メイショウドトウ" | chara == "フィー" ~ "和多田美咲"
+ )) %>% as.data.frame()
title no chara cv
1 ウマ娘 30 ライスシャワー 石見舞菜香
2 ウマ娘 45 スーパークリーク
3 ウマ娘 58 メイショウドトウ 和多田美咲
4 ライザのアトリエ2 1 ライザ
5 ライザのアトリエ2 2 フィー 和多田美咲
6 推しの子 6 黒川あかね

mutate関数は存在する列を指定するとその列の値を書き換えるが、存在しない列名を指定するとその列を新たに作成する。

> tib %>% mutate(type = case_when(
+ str_detect(title, "^推し") ~ "アニメ",
+ )) %>% as.data.frame()
title no chara cv type
1 ウマ娘 30 ライスシャワー NA
2 ウマ娘 45 スーパークリーク NA
3 ウマ娘 58 メイショウドトウ NA
4 ライザのアトリエ2 1 ライザ NA
5 ライザのアトリエ2 2 フィー NA
6 推しの子 6 黒川あかね NA アニメ

case_when関数で指定した条件は、指定した順に評価されるため、最後の条件の条件式にTRUEを指定すればif文のelseに相当する動作をさせることができる。

> tib %>% mutate(type = case_when(
+ str_detect(title, "^推し") ~ "アニメ",
+ TRUE ~ "ゲーム"
+ )) %>% as.data.frame()
title no chara cv type
1 ウマ娘 30 ライスシャワー NA ゲーム
2 ウマ娘 45 スーパークリーク NA ゲーム
3 ウマ娘 58 メイショウドトウ NA ゲーム
4 ライザのアトリエ2 1 ライザ NA ゲーム
5 ライザのアトリエ2 2 フィー NA ゲーム
6 推しの子 6 黒川あかね NA アニメ

2024年2月 2日 (金)

[R]tibbleの列の順番を並び替える

select関数を使う。引数には並び替えたい順に列名を指定する。すべての列を指定する必要はなく、特定の列だけを指定すると、その順にそれらの列だけからなるtibbleが作成される。引数にeverything関数を指定すると指定した列以外のすべて列という意味になるため、以下の3番目の例のとおり、特定の列だけを前(左側)なり後ろ(右側)なりに移動させたい場合に利用できる。

以下の例では簡潔な表示にするため、表示の際にtibbleはデータフレームに変換している。

> library(tidyverse)
> mei <- c("カナメ", "フレイア", "美雲", "マキナ", "レイナ")
> sei <- c("バッカニア", "ヴィオン", "ギンヌメール", "中島", "プラウラー")
> no <- 1:5
> seiyu <- c("安野希世乃", "鈴木みのり", "小清水亜美", "西田望見", "東山奈央")
> tib <- tibble(no, mei, sei, seiyu)
> as.data.frame(tib)
no mei sei seiyu
1 1 カナメ バッカニア 安野希世乃
2 2 フレイア ヴィオン 鈴木みのり
3 3 美雲 ギンヌメール 小清水亜美
4 4 マキナ 中島 西田望見
5 5 レイナ プラウラー 東山奈央
> tib %>% select(no, seiyu, mei, sei) %>% as.data.frame()
no seiyu mei sei
1 1 安野希世乃 カナメ バッカニア
2 2 鈴木みのり フレイア ヴィオン
3 3 小清水亜美 美雲 ギンヌメール
4 4 西田望見 マキナ 中島
5 5 東山奈央 レイナ プラウラー
> tib %>% select(no, seiyu) %>% as.data.frame()
no seiyu
1 1 安野希世乃
2 2 鈴木みのり
3 3 小清水亜美
4 4 西田望見
5 5 東山奈央
> tib %>% select(no, seiyu, everything()) %>% as.data.frame()
no seiyu mei sei
1 1 安野希世乃 カナメ バッカニア
2 2 鈴木みのり フレイア ヴィオン
3 3 小清水亜美 美雲 ギンヌメール
4 4 西田望見 マキナ 中島
5 5 東山奈央 レイナ プラウラー

2024年2月 1日 (木)

[R]tibbleを特定の列だけのtibbleに変換する

select関数を使う。引数に抜き出したい列を指定すればよい。列の指定は列名でも番号(1~)でも指定できる。接頭辞として!を付けるとその列を除くという意味になる。!の指定には列番号にも使える。:(コロン)を使うことで、その列からその列までという範囲指定もできる。

以下の例では簡潔な表示にするため、表示の際にtibbleはデータフレームに変換している。

> library(tidyverse)
> no <- 1:5
> mei <- c("カナメ", "フレイア", "美雲", "マキナ", "レイナ")
> sei <- c("バッカニア", "ヴィオン", "ギンヌメール", "中島", "プラウラー")
> seiyu <- c("安野希世乃", "鈴木みのり", "小清水亜美", "西田望見", "東山奈央")
> tib <- tibble(no, mei, sei, seiyu)
> tib %>% select(mei, sei) %>% as.data.frame()
mei sei
1 カナメ バッカニア
2 フレイア ヴィオン
3 美雲 ギンヌメール
4 マキナ 中島
5 レイナ プラウラー
> tib %>% select(!no) %>% as.data.frame()
mei sei seiyu
1 カナメ バッカニア 安野希世乃
2 フレイア ヴィオン 鈴木みのり
3 美雲 ギンヌメール 小清水亜美
4 マキナ 中島 西田望見
5 レイナ プラウラー 東山奈央
> tib %>% select(2, 3) %>% as.data.frame()
mei sei
1 カナメ バッカニア
2 フレイア ヴィオン
3 美雲 ギンヌメール
4 マキナ 中島
5 レイナ プラウラー
> tib %>% select(!1) %>% as.data.frame()
mei sei seiyu
1 カナメ バッカニア 安野希世乃
2 フレイア ヴィオン 鈴木みのり
3 美雲 ギンヌメール 小清水亜美
4 マキナ 中島 西田望見
5 レイナ プラウラー 東山奈央
> tib %>% select(!(1:3)) %>% as.data.frame()
seiyu
1 安野希世乃
2 鈴木みのり
3 小清水亜美
4 西田望見
5 東山奈央

« 2024年1月 | トップページ | 2024年3月 »

無料ブログはココログ

■■

■■■