データフレームの操作(2).R
要約
・long/wide形式に対してstringr::str_replace()で置換してみた
・当然longの方が素直な挙動
・str_replace()は1セットずつ置換しよう
stringr::str_replace()でデータを見やすくする
rarityを数字で表していたけれど、人が見るデータとしては、当然のように見やすいデータではない。rarityはあくまでもNやRであって、1や2という数字ではないからだ。
そこで、long/wide形式のデータフレームにstr_replace()を適用して置換し、その違いを見てみる。
まずlong形式に適用すると、当然こうなる。期待通りの出力だ。
> gacha.l$rarity %>% head(10)
[1] 3 3 1 4 3 2 4 3 4 4
> gacha.l$rarity %>% str_replace("3","SR") %>% head(10)
[1] "SR" "SR" "1" "4" "SR" "2" "4" "SR" "4" "4"
一方、wide型の値部分(2:11列)に適用するとこうなる。
> gacha[,2:11] %>% str_replace("3", "SR") %>% head()
[1] "c(SR, 1, 2, 5, 4, 5, 2, 1, 2, 4)" "c(SR, 5, 4, 2, 4, 3, 3, 4, 4, 3)"
[3] "c(1, 5, 4, SR, 5, 1, 1, 4, 4, 5)" "c(4, 4, 4, SR, 1, 1, 2, 2, 1, 4)"
[5] "c(SR, 1, 1, 3, 3, 2, 3, 3, 5, 4)" "c(2, 5, SR, 5, 3, 5, 2, 5, 4, 2)"
gachaの各列の変換結果が各要素にベクタとして格納されているのかなと思ったら、よく見るとこの場合には文字列型になっている(”SR”ではない)。残念。
まあ、間違えてgacha.l$rarityじゃなくてgacha.lのデータフレーム全体を入力してしまったときにおかしいことが分かっただろという話はさておき。残念。
もちろん、for文を使って1列ごとに処理することも可能で、それはそれで必要な場面はある。ただ、とにかくベクタで入力しないとダメだよ、ってのは身に染みて分かった。
str_replace()で複数条件を同時処理できないか
1~5まで1つずつ置換するのめんどくさーい。
> gacha.l$rarity %>%
str_replace(c("1", "2", "3", "4", "5"), c("N", "R", "SR", "SSR", "UR"))
[1] "3" "3" "1" "SSR" "3" "2" "4" "SR" "SSR" "4" "N" "5" "5" "SSR" "1"
[16] "5" "4" "1" "5" "1" "2" "4" "4" "SSR" "1" "3" "5" "2" "5" "4"
[31] "5" "R" "SR" "3" "3" "5" "R" "2" "5" "1" "4" "4" "5" "1" "3"
[46] "3" "5" "4" "5" "UR" "5" "3" "1" "1" "2" "5" "5" "4" "5" "UR"
[61] "2" "3" "1" "2" "3" "2" "3" "SR" "5" "UR" "N" "4" "4" "2" "3"
[76] "5" "1" "SR" "SSR" "1" "2" "4" "4" "1" "UR" "4" "5" "2" "SSR" "3"
[91] "4" "3" "5" "SSR" "4" "2" "R" "5" "SSR" "1"
> gacha.l$rarity %>% str_replace(c("1", "2", "3"), c("N", "R", "SR"))
[1] "3" "3" "1" "4" "3" "2" "4" "3" "4" "4" "1" "5" "5" "4" "1" "5" "4" "1"
[19] "5" "1" "2" "4" "4" "4" "N" "3" "5" "2" "5" "4" "5" "R" "SR" "3" "3" "5"
[37] "2" "R" "5" "N" "4" "4" "5" "1" "SR" "3" "5" "4" "5" "5" "5" "3" "1" "1"
[55] "2" "5" "5" "4" "5" "5" "2" "3" "1" "2" "3" "2" "3" "3" "5" "5" "1" "4"
[73] "4" "R" "SR" "5" "1" "SR" "4" "1" "2" "4" "4" "1" "5" "4" "5" "2" "4" "SR"
[91] "4" "3" "5" "4" "4" "2" "2" "5" "4" "N"
> gacha.l$rarity %>% str_replace(c("1", "2"), c("N", "R"))
[1] "3" "3" "N" "4" "3" "R" "4" "3" "4" "4" "N" "5" "5" "4" "N" "5" "4" "1" "5" "1" "2" "4" "4"
[24] "4" "N" "3" "5" "R" "5" "4" "5" "R" "3" "3" "3" "5" "2" "R" "5" "1" "4" "4" "5" "1" "3" "3"
[47] "5" "4" "5" "5" "5" "3" "N" "1" "2" "5" "5" "4" "5" "5" "2" "3" "N" "R" "3" "R" "3" "3" "5"
[70] "5" "N" "4" "4" "R" "3" "5" "N" "3" "4" "1" "2" "4" "4" "1" "5" "4" "5" "R" "4" "3" "4" "3"
[93] "5" "4" "4" "R" "2" "5" "4" "1"
というわけで、試しにc()でstringとreplacementを指定してみた。
命令としては通ってしまうのだけれど、挙動がちょっとおかしい。stringとreplacementの対応は正しそうなのだけれど、まばらに置換されてしまう。
ここは地道に1組ずつ置換するしかないようだ。
> gacha.l$rarity %<>% str_replace("1", "N")
> gacha.l$rarity %<>% str_replace("2", "R")
> gacha.l$rarity %<>% str_replace("3", "SR")
> gacha.l$rarity %<>% str_replace("4", "SSR")
> gacha.l$rarity %<>% str_replace("5", "UR")
> gacha.l
# A tibble: 100 x 3
set time rarity
<int> <chr> <chr>
1 1 V1 SR
2 1 V2 SR
3 1 V3 N
4 1 V4 SSR
5 1 V5 SR
6 1 V6 R
7 1 V7 SSR
8 1 V8 SR
9 1 V9 SSR
10 1 V10 SSR
# ... with 90 more rows
めんどくさかったので、magrittr::%<>%を使って、上書きのパイプ処理を行っている。組が多くなったらfor文でいいだろう。
めんどくさいは発明の父だって誰かが言ってたなあ。ちょっと間違ってる気もするけど。
> gacha.l %>% pivot_wider(names_from = time, values_from = rarity)
# A tibble: 10 x 11
set V1 V2 V3 V4 V5 V6 V7 V8 V9 V10
<int> <chr> <chr> <chr> <chr> <chr> <chr> <chr> <chr> <chr> <chr>
1 1 SR SR N SSR SR R SSR SR SSR SSR
2 2 N UR UR SSR N UR SSR N UR N
3 3 R SSR SSR SSR N SR UR R UR SSR
4 4 UR R SR SR SR UR R R UR N
5 5 SSR SSR UR N SR SR UR SSR UR UR
6 6 UR SR N N R UR UR SSR UR UR
7 7 R SR N R SR R SR SR UR UR
8 8 N SSR SSR R SR UR N SR SSR N
9 9 R SSR SSR N UR SSR UR R SSR SR
10 10 SSR SR UR SSR SSR R R UR SSR N
ついでにwideにしてみた。10行10列のガチャ結果がすべて文字列に置換できていることがわかる。
今日はここまで。