« 2025年11月 | トップページ | 2026年1月 »

2025年12月31日 (水)

[R]文字列が数値に変換できるかどうか判定する

Rは、文字列が数値に変換できるかどうか判定する関数は、初期状態では実装されていない。そのため、次のような自作関数を使用する。

is_numeric <- function(s) {return(!is.na(suppressWarnings(as.numeric(s))))}

動作例は以下のとおり。数値に変換できない文字列はNAが返されるが、suppressWarnings関数により警告の表示が抑制されるため、そのままis.na関数で変換できたかどうか判定することができる。

> is_numeric(" ")
[1] FALSE
> is_numeric("1")
[1] TRUE
> is_numeric("2.0")
[1] TRUE
> is_numeric(" 3.0 ")
[1] TRUE
> is_numeric("4.e4")
[1] TRUE
> is_numeric("Senadia")
[1] FALSE
> is_numeric("セナディア")
[1] FALSE

2025年12月30日 (火)

[R]文字列の長さを得る

stringrパッケージのstr_length関数かstr_width関数を使う。str_length関数は文字数を返す。str_width関数は、文字列を等幅フォントで表示される際の幅(半角英数字が1)を返す。最後の例のとおり、サロゲートペアの文字(𩹉)も幅が2と判定されている。

> s <- c("崩壊3rd", "鈴木みのり", "セナディア", "補塡する")
> s <- c(s, paste0(rawToChar(as.raw(c(0xf0, 0xa9, 0xb9, 0x89))), "(飛魚)"))
> s
[1] "崩壊3rd" "鈴木みのり" "セナディア" "補塡する" "𩹉(飛魚)"
> library(stringr)
> str_length(s)
[1] 5 5 5 4 5
> str_width(s)
[1] 7 10 10 8 10

2025年12月26日 (金)

[R]空白を追加した指定の長さの文字列を得る

いわゆる空白埋めをした文字列を得る方法。stringrパッケージのstr_pad関数を使う。指定の文字列の長さより短い長さを指定すると文字列がそのまま返される。

> library(stringr)
> s <- "SENADIA"
> s
[1] "SENADIA"
> str_pad(s, 10)
[1] " SENADIA"
> str_pad(s, 5)
[1] "SENADIA"

デフォルトでは、文字列の長さは、等幅フォントで表示される際の幅(半角英数字が1)で処理する。これを文字数で処理する場合はuse_widthオプションにFALSEを指定する。

> s <- "崩壊3rd"
> str_pad(s, 7)
[1] "崩壊3rd"
> str_pad(s, 7, use_width = FALSE)
[1] " 崩壊3rd"
デフォルトでは文字列の先頭に空白(0x20)が追加される。sideオプションを使うと、先頭か末尾か先頭・末尾のいずれかを指定できる。padオプションに文字を指定するとその文字が追加される。
> s <- "セナディア"
> str_pad(s, 7, side = "left", use_width = FALSE)
[1] " セナディア"
> str_pad(s, 7, side = "right", use_width = FALSE)
[1] "セナディア "
> str_pad(s, 7, side = "both", use_width = FALSE)
[1] " セナディア "
> str_pad(s, 7, side = "both", pad = "*", use_width = FALSE)
[1] "*セナディア*"

2025年12月24日 (水)

[R]2つの列による重複を調べてその重複の数を表示する

tibbleを使用してgroup_by関数で重複を調べたい列を指定し、summarize関数に渡す。ただ渡すだけの場合は、重複する行を削除するだけになってしまうので、それぞれの重複の数を数えるためにsummarize関数内でn関数を使う。簡潔な表記にするため、画面表示はデータフレームで行っている。

> library(tidyverse)
> s1 <- c("AA", "AA", "AA", "AA", "BB", "BB", "BB", "CC", "CC")
> s2 <- c("aa", "aa", "aa", "bb", "bb", "bb", "cc", "cc", "dd")
> tib <- tibble(s1, s2)
> tib |> as.data.frame()
s1 s2
1 AA aa
2 AA aa
3 AA aa
4 AA bb
5 BB bb
6 BB bb
7 BB cc
8 CC cc
9 CC dd
> tib |> group_by(s1, s2) |> summarize() |> as.data.frame()
`summarise()` has grouped output by 's1'. You can override using the `.groups` argument.
s1 s2
1 AA aa
2 AA bb
3 BB bb
4 BB cc
5 CC cc
6 CC dd
> tib |> group_by(s1, s2) |> summarize(n = n()) |> as.data.frame()
`summarise()` has grouped output by 's1'. You can override using the `.groups` argument.
s1 s2 n
1 AA aa 3
2 AA bb 1
3 BB bb 2
4 BB cc 1
5 CC cc 1
6 CC dd 1
> tib |> group_by(s1, s2) |> summarize(n = n()) |> filter(n > 1) |> as.data.frame()
`summarise()` has grouped output by 's1'. You can override using the `.groups` argument.
s1 s2 n
1 AA aa 3
2 BB bb 2

2025年12月23日 (火)

[R]文字列が指定の正規表現パターンとマッチするかどうか調べる

grep関数を使うと、指定の正規表現パターンにマッチするかどうか簡単に調べることができる。要素が複数のベクトルを対象とすることができ、マッチする要素がある場合はそのインデックスを返す。マッチする要素がない場合は長さが0の数値型ベクトルが返される。インデックスではなく要素自体を返すには、valueオプションにTRUEを指定する。

> s <- c("石見舞菜香", "鈴木みのり", "瀬戸麻沙美", "和多田美咲")
> grep("美", s)
[1] 3 4
> grep("美$", s)
[1] 3
> grep("希世乃", s)
integer(0)
> grep("美$", s, value = TRUE)
[1] "瀬戸麻沙美"
> grep("美[^$]", s, value = TRUE)
[1] "和多田美咲"

2025年12月22日 (月)

[R]ベクトルの各要素にまとめて演算を行う

Rでは、プログラミング言語でいうところの変数はベクトルといい、値や情報を一つ以上まとめて格納できる配列である。そのため、特定の処理以外は、演算は原則として各要素に一つずつまとめて行うことになる。

> d <- 8
> print(2 ^ d)
[1] 256
> d <- c(0, 1, 2, 3, 4, 5, 6, 7, 8)
> print(2 ^ d)
[1] 1 2 4 8 16 32 64 128 256
> s <- c("石見舞菜香", "鈴木みのり", "野口瑠璃子", "和多田美咲")
> print(paste(s , "さん", sep = ""))
[1] "石見舞菜香さん" "鈴木みのりさん" "野口瑠璃子さん" "和多田美咲さん"

演算の戻り値は、元のベクトルと同じ要素数を持つベクトルになる。そのため、それをそのまま次の演算に使用することができる。

> s <- c("瀬戸麻沙美", "優木かな")
> print(paste(s , "さん", sep = ""))
[1] "瀬戸麻沙美さん" "優木かなさん"
> print(paste(s , "さん", sep = "") |> paste("、すごくかわいい", sep = ""))
[1] "瀬戸麻沙美さん、すごくかわいい" "優木かなさん、すごくかわいい"

すべての演算をまとめて行うことができるわけではないことに注意。例えば、if文の条件式は一つの要素しか扱うことができず、要素の数が一つではないベクトルを指定するとエラーが発生する。

> if (s == "石見舞菜香") print("ライスシャワー")
if (s == "石見舞菜香") print("ライスシャワー") でエラー:
the condition has length > 1
> if (s[1] == "石見舞菜香") print("ライスシャワー")
[1] "ライスシャワー

2025年12月17日 (水)

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

stringrパッケージのstr_flatten関数を使う。要素を連結させるベクトルは一つしか与えることができない。デフォルトでは要素の間には何も挟まずに連結するが、第二引数かcollapseオプションに文字列を指定すると、要素の間にその文字列を挟んで連結する。戻り値は当然長さが1の文字列型ベクトル(A string, i.e. a character vector of length 1.)。

> library(stringr)
> s <- c("マクロスΔ","カナメ役", "安野希世乃さん", "かわいい")
> print(s)
[1] "マクロスΔ" "カナメ役" "安野希世乃さん" "かわいい"
> str_flatten(s)
[1] "マクロスΔカナメ役安野希世乃さんかわいい"
> str_flatten(s, ",")
[1] "マクロスΔ,カナメ役,安野希世乃さん,かわいい"
> str_flatten(s, collapse = ",")
[1] "マクロスΔ,カナメ役,安野希世乃さん,かわいい"

2025年12月16日 (火)

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

paste関数にcollapseオプションを指定して使う。paste関数はデフォルトでは引数に与えた1つ以上の文字列型ベクトル同士を連結しようとする。collapseオプションに何かしら文字列を与えると、与えた文字列型ベクトルの要素を連結する。collapseオプションに指定した文字列を、要素の間に挟んで連結する。

> s <- c("マクロスΔ","カナメ役", "安野希世乃さん", "かわいい")
> paste(s)
[1] "マクロスΔ" "カナメ役" "安野希世乃さん" "かわいい"
> paste(s, collapse = "")
[1] "マクロスΔカナメ役安野希世乃さんかわいい"
> paste(s, collapse = ",")
[1] "マクロスΔ,カナメ役,安野希世乃さん,かわいい"

2025年12月15日 (月)

[R]文字列の末尾から文字数を指定して文字列を取り出す

stringrパッケージのstr_sub関数を使う。第二引数に文字数を負数にして指定すると、末尾から何文字という指定になる。

> library(stringr)
> s <- c("鈴木みのりさん、かわいい", "瀬戸麻沙美さん、かわいい")
> str_sub(s, -10) # 末尾から10文字目まで
[1] "みのりさん、かわいい" "麻沙美さん、かわいい"

2025年12月14日 (日)

[R]文字列の末尾から文字数を指定して文字列を取り出す

baseパッケージには、文字列の末尾から文字数を指定して文字列を取り出せる関数(VBAであればRight関数)は搭載されていない。この動作を実現させるには、nchar関数とsubstr関数を組み合わせて使う。

> s <- c("鈴木みのりさん、かわいい", "瀬戸麻沙美さん、かわいい")
> nchar(s)
[1] 12 12
> n <- 10 # 末尾から取り出す文字数を指定
> substr(s, nchar(s) - n + 1, nchar(s)) # 末尾から10文字目まで取り出す
[1] "みのりさん、かわいい" "麻沙美さん、かわいい"

stringrパッケージのstr_sub関数を使うと、少しだけ簡単に実現することができる。

2025年12月12日 (金)

[R]文字列の先頭から文字数を指定して文字列を取り出す

stringrパッケージのstr_sub関数を使う。第二引数を指定せず第三引数に正数を指定すると、先頭から何文字まで取り出すという指定になる。

> library(stringr)
> s <- c("鈴木みのりさん、かわいい", "瀬戸麻沙美さん、かわいい")
> str_sub(s, , 5) # 先頭から5文字目まで
[1] "鈴木みのり" "瀬戸麻沙美"
> str_sub(s, , 7) # 先頭から7文字目まで
[1] "鈴木みのりさん" "瀬戸麻沙美さん"

2025年12月11日 (木)

[R]文字列の先頭から文字数を指定して文字列を取り出す

baseパッケージには、文字列の先頭から文字数を指定して文字列を取り出せる関数(VBAであればLeft関数)は搭載されていない。この動作を実現させるには、substr関数を使う。

> s <- c("鈴木みのりさん、かわいい", "瀬戸麻沙美さん、かわいい")
> substr(s, 1, 5) # 先頭から5文字目まで
[1] "鈴木みのり" "瀬戸麻沙美"
> substr(s, 1, 7) # 先頭から7文字目まで
[1] "鈴木みのりさん" "瀬戸麻沙美さん"

stringrパッケージのstr_sub関数を使うと、少しだけ簡単に実現することができる。

2025年12月10日 (水)

[R]文字列の一部を取り出す

stringrパッケージのstr_sub関数を使う。第二引数に取り出したい文字列が始まる位置を、第三引数に終わる位置をそれぞれ先頭から何文字目か(1~)を指定する。それぞれ引数は省略することができ、省略した場合は以下のようになる。また負数を指定することもでき、その場合の動作は以下のようになる。

> library(stringr)
> s <- c("鈴木みのりさん、かわいい", "瀬戸麻沙美さん、かわいい")
> str_sub(s, 3, 5) # 3~5文字目
[1] "みのり" "麻沙美"
> str_sub(s, 3) # 3文字目以降すべて
[1] "みのりさん、かわいい" "麻沙美さん、かわいい"
> str_sub(s, , 5) # 先頭から5文字目まで
[1] "鈴木みのり" "瀬戸麻沙美"
> str_sub(s, -10) # 末尾から10文字目まで
[1] "みのりさん、かわいい" "麻沙美さん、かわいい"
> str_sub(s, , -8) # 末尾から8文字取り除く
[1] "鈴木みのり" "瀬戸麻沙美"

2025年12月 9日 (火)

[R]文字列の一部を取り出す

substr関数を使う。第二引数に取り出したい文字列が始まる位置を、第三引数に終わる位置をそれぞれ先頭から何文字目か(1~)を指定する。引数は省略することができない。

> s <- c("鈴木みのりさん、かわいい", "瀬戸麻沙美さん、かわいい")
> substr(s, 3, 5)
[1] "みのり" "麻沙美"
> substr(s, 3)
substr(s, 3) でエラー:
引数 "stop" がありませんし、省略時既定値もありません
> substr(s, 3, 12)
[1] "みのりさん、かわいい" "麻沙美さん、かわいい"

2025年12月 6日 (土)

[R]正規表現を使用して文字列型ベクトルから特定の文字列を含む要素を取り出す

grep関数を使う。検索する文字列の指定には正規表現が適用される。検索対象にベクトルを扱うことができ、デフォルトでは指定した正規表現のパターンに一致する要素のインデックスを返す。要素自体を返すようにするにはvalueオプションにTRUEを指定する。

> cv <- c("石見舞菜香さん", "上田麗奈さん", "鈴木みのりさん", "瀬戸麻沙美さん")
> cv <- append(cv, c("のぐちゆりさん", "優木かなさん", "和多田美咲さん"))
> grep("美", cv)
[1] 4 7
> grep("美", cv, value = TRUE)
[1] "瀬戸麻沙美さん" "和多田美咲さん"
> grep("美さん$", cv, value = TRUE)
[1] "瀬戸麻沙美さん"
> grep("[の木]", cv, value = TRUE)
[1] "鈴木みのりさん" "のぐちゆりさん" "優木かなさん"
> grep("(石見|優木)", cv, value = TRUE)
[1] "石見舞菜香さん" "優木かなさん"

一致する要素がない場合は、長さが0のベクトルを返す。

> grep("令", cv)
integer(0)
> grep("令", cv, value = TRUE)
character(0)

2025年12月 5日 (金)

[R]Outlookのメールアドレス入力欄よりコピペしたテキストからアドレス一覧を作成する

Outlookのメール作成のウィンドウで、メールアドレスの入力欄よりコピペしたテキストは、例えば以下のような1行のテキストになるはず。

フレイア <freyja@macross.jp>; 美雲 <mikumo@macross.jp>; カナメ <kaname@macross.jp>

これを「(名前),(メールアドレス)」に変換する方法。

名前とメールアドレスをそれぞれキャプチャしてグループ化して、それらのグループを利用すればよい。

> print(line)
[1] "フレイア <freyja@macross.jp>; 美雲 <mikumo@macross.jp>; カナメ <kaname@macross.jp>"
> words <- unlist(strsplit(trimws(line), "[ ]*;[ ]*"))
> print(words)
[1] "フレイア <freyja@macross.jp>" "美雲 <mikumo@macross.jp>" "カナメ <kaname@macross.jp>"
> lines <- gsub("^(.*)[ ]+<(.*)>$", "\\1,\\2", words)
> print(lines)
[1] "フレイア,freyja@macross.jp" "美雲,mikumo@macross.jp" "カナメ,kaname@macross.jp"

このベクトルを利用してwrite関数でテキストファイルに書き込めば、簡単にCSVファイルを作ることができる。

> write(lines, file = "temp.csv")

出力されたテキストファイル(temp.csv)の中身

フレイア,freyja@macross.jp
美雲,mikumo@macross.jp
カナメ,kaname@macross.jp

2025年12月 3日 (水)

[R]通算打数が5,000以上のプレイヤーのホームラン率と三振率の散布図(「Rによるセイバーメトリクス入門」(技術評論社)pp.62-63)

散布図の青実線は平滑化曲線。

> library(tidyverse)
> library(ggplot2)
> library(Lahman)
> Batting |> group_by(playerID) |>
+ summarize(tAB = sum(AB, na.rm = TRUE),
+ tHR = sum(HR, na.rm = TRUE),
+ tSO = sum(SO, na.rm = TRUE)) -> long_careers
> Batting_5000 <- filter(long_careers, tAB >= 5000)
> print(as.data.frame(head(Batting_5000)))
playerID tAB tHR tSO
1 aaronha01 12364 755 1383
2 abreubo01 8480 288 1840
3 abreujo02 5494 261 1218
4 adamssp01 5557 9 223
5 adcocjo01 6606 336 1059
6 alfoned01 5385 146 617
> ggplot(Batting_5000,
+ aes(x = tHR / tAB, y = tSO / tAB)) + geom_point() + geom_smooth() -> g
> print(g)
`geom_smooth()` using method = 'loess' and formula = 'y ~ x'

R_sabermetrics_fig2_9

2025年12月 2日 (火)

[R]文字列を1文字ずつに分割する

stringrパッケージのstr_split関数を使う。分割指定の正規表現パターン(第2引数)に "" を指定すると、第1引数に与えた文字列を1文字ずつに分割する。

> s <- c("和多田美咲さん、かわいい", "優木かなさん、かわいい")
> print(s)
[1] "和多田美咲さん、かわいい" "優木かなさん、かわいい"
> library(stringr)
> str_split(s, "")
[[1]]
[1] "和" "多" "田" "美" "咲" "さ" "ん" "、" "か" "わ" "い" "い"
[[2]]
[1] "優" "木" "か" "な" "さ" "ん" "、" "か" "わ" "い" "い"

« 2025年11月 | トップページ | 2026年1月 »

無料ブログはココログ

■■

■■■