DB/R/統計/データサイエンス/投資話についてつらつらと

世のため自分のためのアウトプット

R Trouble Shooting

【R言語の備忘録】data.frame(list)型でデータの置換(gsub)を行う方法について

更新日:

gsubをdata.frameに使用した時に少し困ったので、備忘録を残しておきます。

~目次~

1. gsubの基本的な使い方

2. gsbuをdata.frameに使用した時の問題

3. 解決策

4. [おまけ]listへのgsubの適用

1. gsubの基本的な使い方

gsubは文字列の変換を行う関数で、基本的な使い方は以下になります。


gsub(pattern, replacement, x, ignore.case = FALSE, perl = FALSE,
     fixed = FALSE, useBytes = FALSE)

#シンプルに使うと以下
gsub(変更する文字列, 変換後の文字列, 対象のデータ)

試してみます。


> test <- "テストの結果は10点でした"
> test
[1] "テストの結果は10点でした"
> gsub("10", "95",test)
[1] "テストの結果は95点でした"

上記のように"10"を"95"に変えることができました。
便利ですね。

2. gsbuをdata.frameに使用した時の問題

gsub関数自体は、Rの他の関数と同様にベクトルにもそのまま使えます。

> tmp2
[1] "1,000" "2,000" "3,000"
> gsub(",","",tmp2)
[1] "1000" "2000" "3000"

上記では数字に入っている","を削除しました。(変換後の文字列を""にすることで、当該の文字列を削除できます)

しかし、data.frameにgsubを使用すると、以下のようにおかしな結果になります。


> tmp <- data.frame(x=c("1,000","2,000","3,000"), y=c("1,999","2,999","3,999"))
> tmp
      x     y
1 1,000 1,999
2 2,000 2,999
3 3,000 3,999
> gsub(",","",tmp)
[1] "1:3" "1:3"

こういう時に、lapplyやsapplyを使用することを思いつくかもしれませんが、gsubは第一変数が対象のデータではないため、使用できません。
無理やり実行すると、以下のようにエラーが出ます。


> lapply(tmp,gsub,",","")
$x
[1] ""

$y
[1] ""

 警告メッセージ: 
1:  FUN(X[[i]], ...) で: 
   引数 'pattern' は 1 を超える長さなので、最初の要素だけが使われます 
2:  FUN(X[[i]], ...) で: 
   引数 'pattern' は 1 を超える長さなので、最初の要素だけが使われます

3. 解決策

data.frame型には直接持ってこれないので、matrix型にしてから適用します。


> gsub(",","",as.matrix(tmp))
     x      y     
[1,] "1000" "1999"
[2,] "2000" "2999"
[3,] "3000" "3999"

ただし、このままではdata.frameがmatrixになってしまっているので、as.data.frameでdata.frame型に戻してあげます。


> class(gsub(",","",as.matrix(tmp)))
[1] "matrix"
>
> tmp_after <- as.data.frame(gsub(",","",as.matrix(tmp)))
> tmp_after; class(tmp_after)
     x    y
1 1000 1999
2 2000 2999
3 3000 3999
[1] "data.frame"

無事gsub関数で変換することができました。

4. [おまけ]listへのgsubの適用

listにgsubを適用すると、予想通りdata.frameと同様にうまくいきません。


> tmp_list <- list(x=c("1,000","2,000"), y=c("1,999","2,999"))
> gsub(",","",tmp_list)
[1] "c(\"1000\" \"2000\")" "c(\"1999\" \"2999\")"

listにはas.matrixも効かないため以下のどちらかしかないかなと思います。

unlistを使う

unlistで一時的にベクトルに→gsubを適用→list化の流れです。


> tmp_list_2 <- gsub(",","",unlist(tmp_list));tmp_list_2
    x1     x2     y1     y2 
"1000" "2000" "1999" "2999"

> tmp_list_after <- list(x=tmp_list_2[1:2], y=tmp_list_2[3:4]);tmp_list_after $x x1 x2 "1000" "2000"

$y y1 y2 "1999" "2999"

 for文を使う

諦めて素直にfor文を使います。ただし、この方法だとリストの要素名が消えてしまいますね。


> tmp_list_after_2 <- list()
> for (i in 1:length(tmp_list)) tmp_list_after_2[[i]] <- gsub(",","",tmp_list[[i]])
> tmp_list_after_2 
[[1]]
[1] "1000" "2000"

[[2]]
[1] "1999" "2999"

まあ、あまりlist型に直接gsubを使うことはないかもしれませんが。。。

-R, Trouble Shooting

Copyright© 世のため自分のためのアウトプット , 2020 All Rights Reserved Powered by STINGER.