Rで、良いSudachi Lifeを送ってます（途中だけど）

# 以前の記事

https://qiita.com/Mitz-TADA/items/ade1806dd4644bfa5a37

で、SudachiPyをRで使う方法を書きました。その続きです。

# 文字列の分割
　`for()`ではなく、`sapply()`関数を使ったコードで考えていきます。
```r
txt <- "吾輩は猫である"
morphemes <- tokenizer$tokenize(txt)
it_morphemes <- iterate(morphemes)
sapply(it_morphemes, function(m) m$surface())
# '吾輩'・'は'・'猫'・'で'・'ある'
```
# 文字列ベクトルの分割
　上のコードの`txt`の代わりに文字列ベクトル`vec_txt`で実行するとエラーになります。
```r
vec_txt <- c("吾輩は猫である", "名前はまだない")
morphemes <- tokenizer$tokenize(vec_txt)
it_morphemes <- iterate(morphemes)
sapply(it_morphemes, function(m) m$surface())
# Error in py_call_impl(callable, dots$args, dots$keywords): TypeError: argument 'text': 'list' object cannot be converted to 'PyString'
```
　最初に文字列ベクトルを`paste()`関数で結合してから、形態素に分割する方法を考えました。
```r
vec_txt <- c("吾輩は猫である", "名前はまだない")
txt <- paste(vec_txt, collapse="")
morphemes <- tokenizer$tokenize(txt)
it_morphemes <- iterate(morphemes)
sapply(it_morphemes, function(m) m$surface())
# '吾輩'・'は'・'猫'・'で'・'ある'・'名前'・'は'・'まだ'・'ない'
```
　しかし、これでは次のような間違いが起こる可能性があります。
```r
vec_txt <- c("ここで", "はきものを脱いでください")
txt <- paste(vec_txt, collapse="")
morphemes <- tokenizer$tokenize(txt)
it_morphemes <- iterate(morphemes)
sapply(it_morphemes, function(m) m$surface())
# 'ここ'・'で'・'は'・'きもの'・'を'・'脱い'・'で'・'ください'
```
　そこで、`lapply()`関数を使いました。
```r
vec_txt <- c("吾輩は猫である", "名前はまだない")
morphemes <- lapply(vec_txt, function(t) tokenizer$tokenize(t))
it_morphemes <- lapply(morphemes, function(m) iterate(m))
vec_morphemes <- unlist(it_morphemes)
sapply(vec_morphemes, function(m) m$surface())
# '吾輩'・'は'・'猫'・'で'・'ある'・'名前'・'は'・'まだ'・'ない'
```
　省略可能（もともと書く必要がない）な部分をなくすと次のようになります。
```r
vec_txt <- c("吾輩は猫である", "名前はまだない")
morphemes <- lapply(vec_txt, tokenizer$tokenize)
it_morphemes <- lapply(morphemes, iterate)
vec_morphemes <- unlist(it_morphemes)
sapply(vec_morphemes, function(m) m$surface())
# '吾輩'・'は'・'猫'・'で'・'ある'・'名前'・'は'・'まだ'・'ない'
```
　すっきり書くために、R 4.1.0より導入されたパイプ演算子`|>`を使ってみました。
```r
c("吾輩は猫である", "名前はまだない") |>
  lapply(tokenizer$tokenize) |>
  lapply(iterate) |>
  unlist() |>
  sapply(function(m) m$surface())
# '吾輩'・'は'・'猫'・'で'・'ある'・'名前'・'は'・'まだ'・'ない'
```
　先程間違いが起こった例も正しく分割されました。
```r
c("ここで", "はきものを脱いでください") |>
  lapply(tokenizer$tokenize) |> lapply(iterate) |> unlist() |>
  sapply(function(m) m$surface())
# 'ここ'・'で'・'はきもの'・'を'・'脱い'・'で'・'ください'
```
# 品詞の表示
　形態素に分割するとともに、品詞も表示するようにしてみました。
```r
"吾輩は猫である" |>
  lapply(tokenizer$tokenize) |> sapply(iterate) |> unlist() |>
  sapply(function(m) c(m$surface(), unlist(m$part_of_speech())[1]))
#     A matrix: 2 × 5 of type chr
# 　吾輩	　は	　猫	　　で	ある	
# 代名詞	助詞	名詞	助動詞	動詞
```
　指定した品詞だけを取り出すことができます。
```r
c("吾輩は猫である", "名前はまだない") |>
  lapply(tokenizer$tokenize) |> sapply(iterate) |> unlist() |>
  sapply(function(m) c(m$surface(), unlist(m$part_of_speech())[1])) ->
  words

pos <- c("名詞","代名詞")
is_select <- TRUE
words[1, words[2,] %in% pos == is_select]
# '吾輩'・'猫'・'名前'
```
　逆に、同じコードで`is_select <- FALSE`とするだけで、指定した品詞以外を取り出すこともできます。
```r
c("吾輩は猫である", "名前はまだない") |>
  lapply(tokenizer$tokenize) |> sapply(iterate) |> unlist() |>
  sapply(function(m) c(m$surface(), unlist(m$part_of_speech())[1])) ->
  words

pos <- c("名詞","代名詞")
is_select <- FALSE
words[1, words[2,] %in% pos == is_select]
# 'は'・'で'・'ある'・'は'・'まだ'・'ない'
```
　今回はここまで、
　それではRでも、良いSudachi Lifeを