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

2024年4月29日 (月)

[R]read_lines関数で様々な文字コードのテキストファイルを読み込む

localeオプションを使用する。はじめに、この動作確認のためのテキストファイルをPowerShellで作成する。それぞれ文字コードがシフトJISとUTF-8(BOM無し)のCSVファイルを作成している。

PS > $lines = "1,セナディア,鈴木みのり", "2,イレイナ,本渡楓"
PS > $odir = (gl).Path
PS > $lines | Out-File -Encoding default ($odir + "\sjis.csv")
PS > [IO.File]::WriteAllLines(($odir + "\utf8nb.csv"), $lines)
PS > Get-Content sjis.csv
1,セナディア,鈴木みのり
2,イレイナ,本渡楓
PS > Get-Content utf8nb.csv -Encoding utf8
1,セナディア,鈴木みのり
2,イレイナ,本渡楓

read_lines関数を使用する際に、localeオプションに文字コードを指定すればよい。以下の例のとおり、デフォルトではUTF-8で読み込もうとするため、UTF-8であれば明示的に指定しなくてもかまわない。

> library(tidyverse)
> read_lines("sjis.csv", progress = FALSE)
[1] "1,<83>Z<83>i<83>f<83>B<83>A,<97><96><U+0602><U+0742><U+0302>" "2,<83>C<83><8c><83>C<83>i,<96>{<93>n<95><96>"
> read_lines("sjis.csv", progress = FALSE, locale = locale(encoding = "SJIS"))
[1] "1,セナディア,鈴木みのり" "2,イレイナ,本渡楓"
> read_lines("utf8nb.csv", progress = FALSE)
[1] "1,セナディア,鈴木みのり" "2,イレイナ,本渡楓"
> read_lines("utf8nb.csv", progress = FALSE, locale = locale(encoding = "UTF-8"))
[1] "1,セナディア,鈴木みのり" "2,イレイナ,本渡楓"

2024年4月23日 (火)

[R]リストの要素に後から名前を付ける

names関数を使う。この関数は特定の要素だけに名前を付けることはできず、全要素一括でなければできないことに注意。名前を付けたくない要素には””を指定する。

> s1 <- c("セナディア", "イレイナ")
> s2 <- c("鈴木みのり", "本渡楓")
> s3 <- c("崩壊3rd", "魔女の旅々")
> lst <- list(s1, s2, s3)
> lst
[[1]]
[1] "セナディア" "イレイナ"
[[2]]
[1] "鈴木みのり" "本渡楓"
[[3]]
[1] "崩壊3rd" "魔女の旅々"
> names(lst) <- c("名前", "声優", "作品")
> lst
$名前
[1] "セナディア" "イレイナ"
$声優
[1] "鈴木みのり" "本渡楓"
$作品
[1] "崩壊3rd" "魔女の旅々"
> names(lst) <- c("名前", "", "作品")
> lst
$名前
[1] "セナディア" "イレイナ"
[[2]]
[1] "鈴木みのり" "本渡楓"
$作品
[1] "崩壊3rd" "魔女の旅々"

2024年4月20日 (土)

[R]要素に名前を付けてリストを作成する

list関数で=演算子を使い、名前を指定すればよい。3つ目の要素のとおりに、指定をしなければ名前はつかない。

> s1 <- c("セナディア", "イレイナ")
> s2 <- c("鈴木みのり", "本渡楓")
> s3 <- c("崩壊3rd", "魔女の旅々")
> lst <- list(chara = s1, `声優` = s2, s3)
> print(lst)
$chara
[1] "セナディア" "イレイナ"
$声優
[1] "鈴木みのり" "本渡楓"
[[3]]
[1] "崩壊3rd" "魔女の旅々"

2024年4月19日 (金)

[R]文字列のハッシュ値を得る

opensslパッケージを使う。以下はハッシュ関数MD5、SHA-1、SHA-256でそれぞれハッシュ値を得た例。

> s <- c("セナディア", "鈴木みのり", "イレイナ", "本渡楓")
> openssl::md5(s)
[1] "b17b3d97c7f19375d1989eaa6d5d7f19"
[2] "2cdcdf384125ac19c173e9517b23847b"
[3] "df7909633e9e58c8fc61f7ddaa996264"
[4] "9adf030a3e1852802deadb793c4eab0f"
> openssl::sha1(s)
[1] "226dda8c2f33794cdefaef027a43e48135abb6c3"
[2] "728d6a009b1700f9759ed2b502a0f673820700d5"
[3] "97fceb672478954169751379650c14b12f76d808"
[4] "be0a600d132eccfb2ed41a0424189efe210e8dff"
> openssl::sha256(s)
[1] "e385677aa0a829d448251e47f3f6cfa4b82951c9df9b53658a29e71cbfb3125d"
[2] "4a806bf1e967f0764841aabcb3e634316f4b19be1dc9244480cd2c26c315db2b"
[3] "4bd95d8e4a10c946842b256f0b7f281d5db587161a8a5658ae3ab5c19543a222"
[4] "443e41893a26ea324275a26f89a48812f7ac0b687bebf0baddadcd0996116405"

digestパッケージのdigest関数でも得ることができるが、こちらは文字列を文字列型ベクトルで与えることができないため、最初の要素しか使用されない。

> digest::digest(s, algo = "md5", serialize = FALSE)
[1] "b17b3d97c7f19375d1989eaa6d5d7f19"
> digest::digest(s, algo = "sha1", serialize = FALSE)
[1] "226dda8c2f33794cdefaef027a43e48135abb6c3"
> digest::digest(s, algo = "sha256", serialize = FALSE)
[1] "e385677aa0a829d448251e47f3f6cfa4b82951c9df9b53658a29e71cbfb3125d"
> digest::digest("セナディア", algo = "sha256", serialize = FALSE)
[1] "e385677aa0a829d448251e47f3f6cfa4b82951c9df9b53658a29e71cbfb3125d"

2024年4月18日 (木)

[R]要素を一つも持たない空のベクトルを作る

要素にNULL指定して代入すればよい。

> s <- c(NULL)
> print(s)
NULL
> length(s)
[1] 0

空のベクトルが何の役に立つかというと、制御構文の都合でベクトルに値を代入だけをしたい場合は、最初に空にしておくことで、要素を代入する式のみ書けばいいことになり、すっきりしたスクリプトを書くことができる。

> s <- c(NULL)
> c(s, "鈴木みのり", "セナディア")
[1] "鈴木みのり" "セナディア"
> n <- c(NULL)
> print(n)
NULL
> for (i in 1:3) {n <- c(n, i)}
> print(n)
[1] 1 2 3

2024年4月16日 (火)

[R]ベクトルの要素の任意の場所に要素を追加する

append関数を使う。afterオプションには、挿入したい場所の直前のインデックスを指定する。

> s <- c("石見舞菜香", "のぐちゆり")
> s <- append(s, "和多田美咲", after = 1)
> print(s)
[1] "石見舞菜香" "和多田美咲" "のぐちゆり"

afterオプションに0を指定すると先頭に要素を挿入する。afterオプションのデフォルトの値はlength(s)であるので、何も指定しなければ、自動的に最後の要素の次に追加される。

> s <- append(s, "大橋彩香", after = 0)
> print(s)
[1] "大橋彩香" "石見舞菜香" "和多田美咲" "のぐちゆり"
> s <- append(s, "野口瑠璃子")
> print(s)
[1] "大橋彩香" "石見舞菜香" "和多田美咲" "のぐちゆり" "野口瑠璃子"

2024年4月12日 (金)

[R]ベクトルの要素の最後に要素を追加する

c関数を使う。

> s <- c("鈴木みのり", "石見舞菜香", "和多田美咲")
> print(s)
[1] "鈴木みのり" "石見舞菜香" "和多田美咲"
> s <- c(s, "のぐちゆり")
> print(s)
[1] "鈴木みのり" "石見舞菜香" "和多田美咲" "のぐちゆり"

append関数も使える。afterオプションには、挿入したい場所の直前のインデックスを指定できるが、afterオプションのデフォルトの値はlength(s)であるので、最後の要素の次に追加される。

> s <- append(s, "野口瑠璃子")
> print(s)
[1] "鈴木みのり" "石見舞菜香" "和多田美咲" "のぐちゆり" "野口瑠璃子"

2024年4月11日 (木)

[R]ベクトルの要素の先頭に要素を追加する

c関数を使う。

> s <- c("石見舞菜香", "和多田美咲", "のぐちゆり")
> print(s)
[1] "石見舞菜香" "和多田美咲" "のぐちゆり"
> s <- c("鈴木みのり", s)
> print(s)
[1] "鈴木みのり" "石見舞菜香" "和多田美咲" "のぐちゆり"

append関数も使える。afterオプションには、挿入したい場所の直前のインデックスを指定する。この例では先頭(=1)に挿入したいのでその直前である0を指定する。

> s <- append(s, "大橋彩香", after = 0)
> print(s)
[1] "大橋彩香" "鈴木みのり" "石見舞菜香" "和多田美咲" "のぐちゆり"

2024年4月 9日 (火)

[R]ある列の重複を除いた個数を調べる

group_by関数で列を指定してグループ化し、summarize関数で集計する。集計時にn関数を指定すると、その個数を返す。以下はあらかじめ用意したtibbleで実行した例。

> library(tidyverse)
> tib %>% as.data.frame()
nama title seiyu
1 ライスシャワー ウマ娘 石見舞菜香
2 スーパークリーク ウマ娘 優木かな
3 メイショウドトウ ウマ娘 和多田美咲
4 フィー ライザのアトリエ2 和多田美咲
5 黒川あかね 推しの子 石見舞菜香
> tib %>% group_by(title) %>% summarize(nn = n()) %>% as.data.frame()
title nn
1 ウマ娘 3
2 ライザのアトリエ2 1
3 推しの子 1
> tib %>% group_by(seiyu) %>% summarize(nn = n()) %>% as.data.frame()
seiyu nn
1 優木かな 1
2 和多田美咲 2
3 石見舞菜香 2
グループ化には2つ以上の列を同時に指定することもできる。
> tib2 <- bind_rows(tib, slice(tib, c(1, 1, 3)))
> tib2 %>% as.data.frame()
nama title seiyu
1 ライスシャワー ウマ娘 石見舞菜香
2 スーパークリーク ウマ娘 優木かな
3 メイショウドトウ ウマ娘 和多田美咲
4 フィー ライザのアトリエ2 和多田美咲
5 黒川あかね 推しの子 石見舞菜香
6 ライスシャワー ウマ娘 石見舞菜香
7 ライスシャワー ウマ娘 石見舞菜香
8 メイショウドトウ ウマ娘 和多田美咲
> tib2 %>% group_by(title, seiyu) %>% summarize(nn = n()) %>% as.data.frame()
`summarise()` has grouped output by 'title'. You can override using the `.groups` argument.
title seiyu nn
1 ウマ娘 優木かな 1
2 ウマ娘 和多田美咲 2
3 ウマ娘 石見舞菜香 3
4 ライザのアトリエ2 和多田美咲 1
5 推しの子 石見舞菜香 1

2024年4月 7日 (日)

[R]tibbleで特殊な列名を使用して操作する

例えばASCIIの0~9で始まる名前は通常は列名に使用できないが、バックティック(`)で挟むと使用することができるようになる。

> library(tidyverse)
> tib <- tibble(21世紀 = 1:4)
エラー: 想定外のシンボルです ( "tib <- tibble(21世紀" の)
> tib <- tibble(`21世紀` = 1:4)
> tib %>% as.data.frame()
21世紀
1 1
2 2
3 3
4 4
> tib %>% filter(`21世紀` >= 3) %>% as.data.frame()
21世紀
1 3
2 4

2024年4月 6日 (土)

[R]tibbleの行に連番付け、順位付けを行う

連番付けにはrow_number関数、順位付けにはmin_rank関数かdense_rank関数を使う。

row_number関数は行に対して1から始まる連番を作成する。min_rank関数とdense_rank関数は順位付け関数であるが動作が異なり、min_rank関数は指定の列の値に同じ値があった場合は同位としてその次の順位を飛ばすが、dense_rank関数は同じ値があった場合は同位として次の順位は飛ばさない。最後の例のとおり、row_number関数は与えられたtibbleについて1行目から連番を割り当てるが、min_rank関数とdense_rank関数は指定された列の値に基づいて順位付けを行う。順位付けのデフォルトは昇順のため、これを降順にしたい場合は列を指定する際にdesc関数を使用する。

> library(tidyverse)
> tib <- tibble(n = c(20, 20, 30, 10, 40))
> tib %>% arrange(n) %>% mutate(row_number(), min_rank(n), dense_rank(n)) %>% as.data.frame()
n row_number() min_rank(n) dense_rank(n)
1 10 1 1 1
2 20 2 2 2
3 20 3 2 2
4 30 4 4 3
5 40 5 5 4
> tib %>% arrange(n) %>% mutate(row_number(), min_rank(desc(n)), dense_rank(desc(n))) %>% as.data.frame()
n row_number() min_rank(desc(n)) dense_rank(desc(n))
1 10 1 5 4
2 20 2 3 3
3 20 3 3 3
4 30 4 2 2
5 40 5 1 1
> tib %>% mutate(row_number(), min_rank(desc(n)), dense_rank(desc(n))) %>% as.data.frame()
n row_number() min_rank(desc(n)) dense_rank(desc(n))
1 20 1 3 3
2 20 2 3 3
3 30 3 2 2
4 10 4 5 4
5 40 5 1 1

2024年4月 5日 (金)

[R]tibbleから列の値が重複している行を抽出する

group_by関数で列を指定してグループ化し、filter関数とn関数を組み合わせてグループの行数が2以上の行を表示させればよい。最後の例のとおり、二つ以上の列を同時に指定することもできる。

> library(tidyverse)
> tib %>% as.data.frame()
name seiyu
1 ライスシャワー 石見舞菜香
2 ライスシャワー 石見舞菜香
3 メイショウドトウ 和多田美咲
4 メイショウドトウ (調査中)
5 サクラチヨノオー 野口瑠璃子
> tib %>% group_by(name) %>% filter(n() > 1) %>% as.data.frame()
name seiyu
1 ライスシャワー 石見舞菜香
2 ライスシャワー 石見舞菜香
3 メイショウドトウ 和多田美咲
4 メイショウドトウ (調査中)
> tib %>% group_by(name, seiyu) %>% filter(n() > 1) %>% as.data.frame()
name seiyu
1 ライスシャワー 石見舞菜香
2 ライスシャワー 石見舞菜香

2024年4月 4日 (木)

[R]列方向にtibbleを連結する

bind_cols関数を使う。最後の例のとおり、行数が揃わない場合は連結できない。

> library(tidyverse)
> no <- c(40, 45, 58)
> name <- c("ゴールドシチー", "スーパークリーク", "メイショウドトウ")
> seiyu <- c("香坂さき", "優木かな", "和多田美咲")
> tib1 <- tibble(no, name)
> tib2 <- tibble(seiyu)
> tib1 %>% as.data.frame()
no name
1 40 ゴールドシチー
2 45 スーパークリーク
3 58 メイショウドトウ
> tib2 %>% as.data.frame()
seiyu
1 香坂さき
2 優木かな
3 和多田美咲
> bind_cols(tib1, tib2) %>% as.data.frame()
no name seiyu
1 40 ゴールドシチー 香坂さき
2 45 スーパークリーク 優木かな
3 58 メイショウドトウ 和多田美咲
> tib3 <- tibble(seiyu = c("鈴木みのり", "石見舞菜香"))
> tib3 %>% as.data.frame()
seiyu
1 鈴木みのり
2 石見舞菜香
> bind_cols(tib1, tib3)
Error in `bind_cols()`:
! Can't recycle `..1` (size 3) to match `..2` (size 2).
Run `rlang::last_trace()` to see where the error occurred.

2024年4月 3日 (水)

[R]行方向にtibbleを連結する

bind_rows関数を使う。rbind関数と同様に列名を基準にして連結するため、列名の順は異なっていてもかまわない。なお、最後の例のとおり、rbind関数とは異なり列名が一致しない場合はNAを挿入して強制的に連結する。

> library(tidyverse)
> tib1 <- tibble(
+ no = c(40, 45),
+ name = c("ゴールドシチー", "スーパークリーク")
+ )
> tib2 <- tibble(
+ name = c("メイショウドトウ", "サクラチヨノオー"),
+ no = c(58, 69)
+ )
> tib1 %>% as.data.frame()
no name
1 40 ゴールドシチー
2 45 スーパークリーク
> tib2 %>% as.data.frame()
name no
1 メイショウドトウ 58
2 サクラチヨノオー 69
> bind_rows(tib1, tib2) %>% as.data.frame()
no name
1 40 ゴールドシチー
2 45 スーパークリーク
3 58 メイショウドトウ
4 69 サクラチヨノオー
> tib3 <- tibble(
+ no = c(58, 69),
+ seiyu = c("和多田美咲", "野口瑠璃子")
+ )
> tib3 %>% as.data.frame()
no seiyu
1 58 和多田美咲
2 69 野口瑠璃子
> bind_rows(tib1, tib3) %>% as.data.frame()
no name seiyu
1 40 ゴールドシチー <NA> 2 45 スーパークリーク <NA> 3 58 <NA> 和多田美咲
4 69 <NA> 野口瑠璃子

2024年4月 2日 (火)

[R]二つの集合MとNの共通部分M∩Nと和集合M∪Nを得る

共通部分(どちらにも属している要素の集合)M∩Nを得るにはintersect関数を、和集合(少なくとも一方に属する要素の集合)M∪Nを得るにはunion関数を得る。以下、例。

> m <- seq(2, 18, by = 2)
> n <- seq(3, 18, by = 3)
> print(m)
[1] 2 4 6 8 10 12 14 16 18
> print(n)
[1] 3 6 9 12 15 18
> union(m, n)
[1] 2 4 6 8 10 12 14 16 18 3 9 15
> intersect(m, n)
[1] 6 12 18

ベクトルの要素に対して行う処理のため、当然、要素が数値以外でもかまわない。

> s1 <- c("スーパークリーク", "メイショウドトウ", "サクラチヨノオー")
> s2 <- c("メイショウドトウ", "サクラチヨノオー", "メジロアルダン")
> union(s1, s2)
[1] "スーパークリーク" "メイショウドトウ" "サクラチヨノオー" "メジロアルダン"
> intersect(s1, s2)
[1] "メイショウドトウ" "サクラチヨノオー"

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

無料ブログはココログ

■■

■■■