R(文字と文字列)

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年1月29日 (月)

[R]JISコードから区点番号を得る

以下の自作関数kutenToJisは、JISコードを与えると区点番号を返す。

jisToKuten <- function(jis) {
s <- sprintf("%04x", jis)
n1 <- as.integer(sprintf("0x%s", substr(s, 1, 2))) - 0x20
n2 <- as.integer(sprintf("0x%s", substr(s, 3, 4))) - 0x20
return(c(n1, n2))
}

以下の2つの漢字で動作確認をする。

美 - JISコード:0x487e(10進数 18558), 区点番号:4094
雲 - JISコード:0x3140(10進数 12608), 区点番号:1732

動作例。

> jisToKuten <- function(jis) {
+ s <- sprintf("%04x", jis)
+ n1 <- as.integer(sprintf("0x%s", substr(s, 1, 2))) - 0x20
+ n2 <- as.integer(sprintf("0x%s", substr(s, 3, 4))) - 0x20
+ return(c(n1, n2))
+ }
> kuten <- jisToKuten(0x487e)
> print(kuten)
[1] 40 94
> length(kuten)
[1] 2
> kuten <- jisToKuten(12608)
> print(kuten)
[1] 17 32
> length(kuten)
[1] 2

2024年1月28日 (日)

[R]区点番号からJISコードを得る

以下の自作関数kutenToJisは、区点番号を与えるとそのJISコードを返す。

kutenToJis <- function(ku, ten) {
s12 <- as.hexmode(ku + 0x20)
s34 <- as.hexmode(ten + 0x20)
s <- sprintf("0x%s%s", s12, s34)
return(as.integer(s))
}

以下の2つの漢字で動作確認をする。

美 - 区点番号:4094, JISコード:0x487e(10進数 18558)
雲 - 区点番号:1732, JISコード:0x3140(10進数 12608)

動作例。

> kutenToJis <- function(ku, ten) {
+ s12 <- as.hexmode(ku + 0x20)
+ s34 <- as.hexmode(ten + 0x20)
+ s <- sprintf("0x%s%s", s12, s34)
+ return(as.integer(s))
+ }
> kutenToJis(40, 94)
[1] 18558
> jis <- kutenToJis(40, 94)
> print(jis)
[1] 18558
> print(as.hexmode(jis))
[1] "487e"
> jis <- kutenToJis(17, 32)
> print(jis)
[1] 12608
> print(as.hexmode(jis))
[1] "3140"

2024年1月14日 (日)

[R]ランダムに作成された文字列を得る

runif関数とpaste関数を組み合わせて使う。chベクトルには文字列にランダムで割り振る文字を指定し、lenベクトルには得たい文字列の長さを1つだけ指定する。ただし、この方法では一度に一つの文字列しか得ることはできない。

定数LETTERSとlettersにはそれぞれ英大文字と英小文字を含むベクトルのため、これらをそのまま利用すれば英大小文字だけからなるランダムな文字列を作成することができる。当然、記号を適当に含めれば、それらの文字列からなる任意の文字列を作成することができる。

> len <- 10
> ch <- LETTERS
> paste(ch[floor(runif(len, 1, length(ch) + 1))], collapse = "")
[1] "WTHNZZCBIJ"
> paste(ch[floor(runif(len, 1, length(ch) + 1))], collapse = "")
[1] "STATFLICHV"
> len <- 20
> ch <- c(LETTERS, letters, "#", "$", "%", "&")
> paste(ch[floor(runif(len, 1, length(ch) + 1))], collapse = "")
[1] "bBYEODy&DlSZuKcaaykO"
> paste(ch[floor(runif(len, 1, length(ch) + 1))], collapse = "")
[1] "hCYaqYkpWkDbP$HcAZPB"

文字列はRの乱数の規則に則って作成される。そのため、乱数の種をset.seed関数で指定すると、作成される文字列を再現することができる。

> paste(ch[floor(runif(len, 1, length(ch) + 1))], collapse = "")
[1] "XG#C#CwhHgBWKgyVdblP"
> set.seed(20)
> paste(ch[floor(runif(len, 1, length(ch) + 1))], collapse = "")
[1] "xrPd$%FDSUoqApKZSGQt"
> paste(ch[floor(runif(len, 1, length(ch) + 1))], collapse = "")
[1] "bBYEODy&DlSZuKcaaykO"
> set.seed(20)
> paste(ch[floor(runif(len, 1, length(ch) + 1))], collapse = "")
[1] "xrPd$%FDSUoqApKZSGQt"
> paste(ch[floor(runif(len, 1, length(ch) + 1))], collapse = "")
[1] "bBYEODy&DlSZuKcaaykO"

2024年1月13日 (土)

[R]ランダムに作成された文字列を得る

stringiパッケージのstri_rand_strings関数を使う。一度に複数個をベクトルで得ることができる。

> library(stringi)
> stri_rand_strings(1, 14)
[1] "cJBFBNlLVvbqLQ"
> s <- stri_rand_strings(3, 14)
> library(stringi)
> stri_rand_strings(1, 14)
[1] "NJNxejqJl3dgYS"
> s <- stri_rand_strings(3, 10)
> print(s)
[1] "5Y4del2QiL" "9JK3rYewTL" "4IXEI2ADaN"

ヘルプには、文字列の作成に使用される文字についての説明がある。

> ?stri_rand_strings

以下の説明がある。

Usage
stri_rand_strings(n, length, pattern = "[A-Za-z0-9]")

正規表現の書式を模した書式により、使用される文字列の指定ができる。デフォルトでは英大文字、英小文字、英数字だけだが、例えば、#、$、%、&の記号を4つ追加する場合は、以下のように指定をすればよい。$と&は書式を示す文字のため、前に¥を付けなければならないが、¥はエスケープシーケンスを表す記号でもあるため、前に「¥¥」と2つ続けて入力している。

> stri_rand_strings(3, 14, pattern = "[a-z#\\$%\\&]")
[1] "yapn%u$iaguxyj" "#fnkunslor&blp" "v&nro&mvxvpjke"

文字列はRの乱数の規則に則って作成される。そのため、乱数の種をset.seed関数で指定すると、作成される文字列を再現することができる。

> stri_rand_strings(4, 6)
[1] "O45lLP" "L0uBiZ" "XMpBOU" "UNdLx2"
> set.seed(6)
> stri_rand_strings(4, 6)
[1] "bwGNoy" "xlV3du" "5IlFWg" "9hxp7E"
> stri_rand_strings(4, 6)
[1] "kJMuHQ" "W7xl8v" "N3zlhi" "4wyp7Q"
> set.seed(6)
> stri_rand_strings(4, 6)
[1] "bwGNoy" "xlV3du" "5IlFWg" "9hxp7E"
> stri_rand_strings(4, 6)
[1] "kJMuHQ" "W7xl8v" "N3zlhi" "4wyp7Q"

2024年1月10日 (水)

[R]ランダムに作成された文字列を得る

sample関数とpaste関数を組み合わせて使う。sample関数の第2引数に、得たい文字列の長さを指定する。

定数LETTERSとlettersにはそれぞれ英大文字と英小文字を含むベクトルのため、これらをそのまま利用すれば英大小文字だけからなるランダムな文字列を作成することができる。当然、記号を適当に含めれば、それらの文字列からなる任意の文字列を作成することができる。

> LETTERS
[1] "A" "B" "C" "D" "E" "F" "G" "H" "I" "J" "K" "L" "M" "N" "O" "P" "Q" "R" "S" "T" "U" "V" "W" "X" "Y" "Z"
> letters
[1] "a" "b" "c" "d" "e" "f" "g" "h" "i" "j" "k" "l" "m" "n" "o" "p" "q" "r" "s" "t" "u" "v" "w" "x" "y" "z"
> s <- LETTERS
> paste(sample(s, 14, replace = TRUE), collapse = "")
[1] "UJTMRBBANJHZHR"
> paste(sample(s, 14, replace = TRUE), collapse = "")
[1] "PWYFPVJQHJGSNI"
> s <- c(LETTERS, letters)
> paste(sample(s, 14, replace = TRUE), collapse = "")
[1] "QjrFTEySFGwOEG"
> paste(sample(s, 14, replace = TRUE), collapse = "")
[1] "SNRBuCpZdkqpIs"
> s <- c(LETTERS, letters, "#", "$", "%", "&")
> paste(sample(s, 24, replace = TRUE), collapse = "")
[1] "bEimcMQlAHCdRkc%m#GbfifS"
> paste(sample(s, 24, replace = TRUE), collapse = "")
[1] "CVrUHSYWWRPwcrsXF&StkSrK"

2024年1月 6日 (土)

[R]文字列の文字コードを調べる

iconv関数を使う。iconv関数は第1引数に指定した文字列を、toオプションに指定した文字コードに変換する。toオプションだけを指定した場合は変換後の文字列をそのまま返すが、実行環境と文字コードが合わない場合は表示が乱れるので注意。TRUEを指定したtoRawオプションを付けると、戻り値はロウ型になりバイト列で表示されるため、このオプションを使用した利用が推奨される。

以下は、「石見舞菜香」という5つの漢字からなる文字列について、文字コードをバイト列で表示した例。なお、各漢字のそれぞれの文字コードは以下のとおり。実行した環境の文字コードはUTF-8で、JISコードとシフトJISにそれぞれ変換している。toRawオプションにTRUEを指定した場合の戻り値はロウ型かつリストであることに注意。ロウ型はバイト列で表示される。

漢字 JISコード シフトJIS UTF-8
石 0x4050 0x90ce 0xe79fb3
見 0x382b 0x8ca9 0xe8a68b
舞 0x4971 0x9591 0xe8889e
菜 0x3a5a 0x8dd8 0xe88f9c
香 0x3961 0x8d81 0xe9a699

実行例は以下のとおり。

> 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"
> iconv("石見舞菜香", to = "ISO-2022-JP")
[1] "\033$B@P8+Iq:Z9a"
> iconv("石見舞菜香", to = "ISO-2022-JP", toRaw = TRUE)
[[1]]
[1] 1b 24 42 40 50 38 2b 49 71 3a 5a 39 61
> iconv("石見舞菜香", to = "SJIS", toRaw = TRUE)
[[1]]
[1] 90 ce 8c a9 95 91 8d d8 8d 81
> iconv("石見舞菜香", to = "UTF-8", toRaw = TRUE)
[[1]]
[1] e7 9f b3 e8 a6 8b e8 88 9e e8 8f 9c e9 a6 99

iconv関数は現在の環境の文字コードに関係なく、引数に与えた任意の文字コードからなる文字列を、任意の文字コードまたは任意の文字コードによる文字列に変換する関数。よって、以下の例のようにUTF-8環境下でシフトJISに相当するバイト列をロウ型で与えてfromオプションにシフトJISを指定することで、任意の文字コードを変換することができる。最後の例では、符号化文字集合の切り替えを示すエスケープシーケンス(0x1b 0x24 0x42)が先頭に付けられていることに注意。

> ra <- as.raw(c(0x95, 0x91, 0x8d, 0xd8, 0x8d, 0x81))
> iconv(rawToChar(ra), from = "SJIS", to = "UTF-8")
[1] "舞菜香"
> iconv(rawToChar(ra), from = "SJIS", to = "UTF-8", toRaw = TRUE)
[[1]]
[1] e8 88 9e e8 8f 9c e9 a6 99
> iconv(rawToChar(ra), from = "SJIS", to = "ISO-2022-JP", toRaw = TRUE)
[[1]]
[1] 1b 24 42 49 71 3a 5a 39 61

iconv関数の第1引数にベクトルで文字列を与えると、それぞれ変換した値を返す。

> iconv(c("石見舞菜香", "和多田美咲"), to = "SJIS", toRaw = TRUE)
[[1]]
[1] 90 ce 8c a9 95 91 8d d8 8d 81
[[2]]
[1] 98 61 91 bd 93 63 94 fc 8d e7

2023年12月29日 (金)

[R]文字列型ベクトルの要素の文字列を連結する

文字列型ベクトル同士ではなく文字列型ベクトルの要素の文字列同士を連結するには、stringrパッケージのstr_c関数にcollapseオプションを付けて使う。str_c関数は引数に与えたベクトルをベクトルで処理しようとするため、デフォルトでは与えたベクトル同士を連結しようとするが、collapseオプションを使うと、与えた文字列型ベクトルの要素同士を連結する。文字列の間に何も挟みたくなければ""を指定する。

> library(stringr)
> s <- c("石見舞菜香", "優木かな", "和多田美咲")
> str_c(s)
[1] "石見舞菜香" "優木かな" "和多田美咲"
> str_c(s, collapse = "")
[1] "石見舞菜香優木かな和多田美咲"
> str_c(s, collapse = "_")
[1] "石見舞菜香_優木かな_和多田美咲"

2023年12月28日 (木)

[R]絶対パスを表す文字列からファイル名(ディレクトリ名)だけを取り出す

gsub関数を使う。以下はWindows環境下における絶対パス(区切り記号は「¥」)から、ファイル名とそれ以外のディレクトリ名をそれぞれ取り出した例。

> s <- c("C:\\マクロス\\Δ\\カナメ.バッカニア.txt")
> gsub("^.+\\\\", "", s)
[1] "カナメ.バッカニア.txt"
> gsub("\\\\[^\\]+$", "", s)
[1] "C:\\マクロス\\Δ"

2023年12月27日 (水)

[R]文字列型ベクトルの要素の文字列を連結する

文字列型ベクトル同士ではなく文字列型ベクトルの要素の文字列同士を連結するには、paste関数にcollapseオプションを付けて使う。paste関数は引数に与えたベクトルをベクトルで処理しようとするため、デフォルトでは与えたベクトル同士を連結しようとするが、collapseオプションを指定すると、与えた文字列型ベクトル内の文字列を連結する。文字列の間に何も挟みたくなければ""を指定する。

> s <- c("石見舞菜香", "優木かな", "和多田美咲")
> paste(s, sep = "")
[1] "石見舞菜香" "優木かな" "和多田美咲"
> paste(s, collapse = "")
[1] "石見舞菜香優木かな和多田美咲"
> paste(s, collapse = "_")
[1] "石見舞菜香_優木かな_和多田美咲"

より以前の記事一覧

無料ブログはココログ

■■

■■■