No.22370 R 文字列の抽出、突合せ  【明石】 2017/05/28(Sun) 07:22

青木先生,
いつもお世話になり,ありがとうございます,明石と申します。

昨日の質問では,大変にお世話になり,ありがとうございました。

また,Rについて,お聞きしたいことがでてきました。
ご教示をいただければ,大変に助かります。
どうぞよろしくお願いいたします。

ーーー

以下に例示します。
使うデータは,(1)(2)の2つです。

(1) 文字列

  " 政治 経済 政治 社会 経済 国民 "

複数の単語を含む,文字列です。
単語の区切りは,1個以上の半角空白文字です。
文字列の先頭,最後にも,1個以上の半角空白文字があります。

(2) 単語の表(表1とよびます)

ban word
1 政治
2 経済
3 社会
4 外交
5 教育
6 福祉
7 防衛

求めたい出力は,以下にお示しをします表2です。

(1)の文字列から単語を抽出して,
その単語を,(2)表1と突合せをして,表2を作成します。

表2
word freq ban
政治 2 1
経済 2 2
社会 1 3
国民 1 NA

項目の意味は,以下の通りです。
word  抽出した単語
freq  文字列の中の出現度数
ban   表1における位置(行番号)
     もし,表1に単語がない場合には,NA

(1)の文字列から単語を抽出する際に,文字区切りが半角空白1文字ならば,
text <- " 政治 経済 政治 社会 経済 国民 "
s <- strsplit(text, " ")
のように,簡単に取り出しができるのですが,
1個以上の半角空白文字があることから,苦慮しています。

お示しをしました例示は,小さいデータですが,
やりたいデータでは,表1のサイズ,文字列ともに大規模なので,
効率のよい処理も期待しています。

ご教示をいただければ大変に助かります。
どうぞ,よろしくお願いいたします。

No.22371 Re: R 文字列の抽出、突合せ  【青木繁伸】 2017/05/28(Sun) 08:40

先頭,末尾の空白は sub 関数で除去できます
strsplit の区切り文字にも,正規表現が使えます
" +" は,「連続する一個以上の半角空白」を意味します
> s = "      政治      経済    政治 社会   経済 国民          "
> s = sub("^ +", "", s) # 先頭の空白を除去
> # s = sub(" +$", "", s) # 末尾の空白は除去しておかなくてもよい
> unlist(strsplit(s, " +"))
[1] "政治" "経済" "政治" "社会" "経済" "国民"

No.22372 Re: R 文字列の抽出、突合せ  【明石】 2017/05/28(Sun) 11:06

青木先生,
いつもお世話になり,ありがとうございます,明石と申します。

有難いご教示をいただき,誠にありがとうございました。

strsplit関数で,区切り文字の指定に正規表現が利用できることを教えていただきましたので,
今後の活用範囲が広がります。
ありがとうございました。

ご教示いただきましたコードを活用させていただき,
目的の表2の作成に向けて,自分でコードを作成しました。

改善点をご教示いただければ,大変に助かります。
どうぞよろしくお願いいたします。
s <- "      政治      経済    政治 社会   経済 国民          "

s <- sub("^ +", "", s) # 先頭の空白を除去
# s = sub(" +$", "", s) # 末尾の空白は除去しておかなくてもよい

s <- unlist(strsplit(s, " +"))
# [1] "政治" "経済" "政治" "社会" "経済" "国民"

d <- unique(s)
# [1] "政治" "経済" "社会" "国民"

tb1 <- data.frame(
ban = 1:7,
word = c("政治", "経済", "社会", "外交", "教育", "福祉", "防衛"), stringsAsFactors=F )

n <- length(d)

word <- character(n)
freq <- numeric(n)
ban <- numeric(n)

for (i in 1:n) {
word[i] <- d[i]
freq[i] <- length(which(s == d[i]))
ban[i] <- ifelse( any(tb1$word == d[i]), which(tb1$word ==d[i]) ,"NA")
}

tb2 <- data.frame(word, freq, ban)
tb2

word freq ban
1 政治 2 1
2 経済 2 2
3 社会 1 3
4 国民 1 NA
以上,よろしくお願いいたします。

No.22373 Re: R 文字列の抽出、突合せ  【青木繁伸】 2017/05/28(Sun) 14:58

> s = " 政治 経済 政治 社会 経済 国民 "
> word = c("政治", "経済", "社会", "外交", "教育", "福祉", "防衛")

> s = sub("^ +", "", s)
> s = unlist(strsplit(s, " +"))

> freq = table(s) # 集計は table で
> word2 = names(freq)

> ban = unname(sapply(word2, function(w) ifelse(w %in% word, grep(w, word), NA)))
> tb2 = data.frame(word = word2, freq = as.integer(freq), ban=ban)
> tb2
word freq ban
1 経済 2 2
2 国民 1 NA
3 社会 1 3
4 政治 2 1
> # 並べ替えが必要なら以下の2行
> tb2 = tb2[order(ban),]
> rownames(tb2) = seq_along(ban)
> # 結果
> tb2
word freq ban
1 政治 2 1
2 経済 2 2
3 社会 1 3
4 国民 1 NA

No.22374 Re: R 文字列の抽出、突合せ  【明石】 2017/05/28(Sun) 15:17

青木先生,
いつもお世話になり,ありがとうございます,明石と申します。

有難いご教示をいただき,誠にありがとうございました。

今回もまた,大変に良い勉強をさせていただきました。
心から御礼を申し上げます。

● 「統計学関連なんでもあり」の過去ログ--- 048 の目次へジャンプ
● 「統計学関連なんでもあり」の目次へジャンプ
● 直前のページへ戻る