2024年3月 1日 (金)

[R]MySQLのデータベースに接続する

RMySQLパッケージを使う。以下は、あらかじめサービスが稼働しているMySQLのデータベースを一覧表示させた例。データベースに接続するにはdbConnect関数を使う。dbGetQuery関数を使うことでコマンドを実行することができる。すべての作業が終了したらdbDisconnect関数で接続を切断することを忘れない。以下の1~3, 5はMySQLに最初から組み込まれているデータベースで、4のprincessは自作したデータベース。以下のとおりに動作を確認することができる。

dbConnect関数使用時は、アカウント、パスワード、接続先を指定する必要がある。以下の例では、rootアカウントでパスワードはpassとしている。hostにlocalhostを指定すると、ローカルホストに接続する。

> library(RMySQL)
> drv <- dbDriver("MySQL")
> con <- dbConnect(drv, user = 'root', password = 'pass', host = 'localhost')
> dbGetQuery(con, "show databases")
Database
1 information_schema
2 mysql
3 performance_schema
4 princess
5 sys
> dbDisconnect(con)
[1] TRUE

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]], ...) でエラー: 添え字が許される範囲外です

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

無料ブログはココログ

■■

■■■