復習 1.

3. 英文テキスト一般を対象に、語彙頻度一覧表を作成する独自関数を作ってみましょう。

文字化け問題:記号が記号ではなく別の文字になってしまう

  • アポストロフィ
  • 引用符

(^^♪ 解答例

myWordListG <- function(){
 lines.tmp <- scan(choose.files(), what="char", sep="\n")
 data.tmp <- lines.tmp
 data.tmp <- data.tmp[data.tmp != ""]
 tmp4 <- gsub("[[:punct:]]", " ", data.tmp)
 tmp5 <- gsub(" +", " ", tmp4)
 tmp6 <- tolower(tmp5)
 tmp7 <- strsplit(tmp6, " ")
 tmp8 <- unlist(tmp7)
 token <- sort(tmp8)
 type <- unique(token)
 table(token)
}

実行

myWordListG()

復習 2.

2. 総語数とTTRの関係について調べてみる。


sort(table(token))

sort(table(token), decreasing = T)

plot(head(sort(table(token), decreasing = T)))

head(sort(table(token), decreasing = T), 20)

plot(head(sort(table(token), decreasing = T), 20))

Biden Speech Word List

Guiraid index : 語彙の多様性指標:TTRの改良版

myGI <- function(d){
  tmp4 <- gsub("[[:punct:]]", " ", d)
  tmp5 <- gsub("  +", " ", tmp4)
  tmp6 <- tolower(tmp5)
  tmp7 <- strsplit(tmp6, " ")
  tmp8 <- unlist(tmp7)
  token <- sort(tmp8)
  type <- unique(token)
# length(type)/length(token)
  length(type)/sqrt(length(token))
}
myGI(ns502.data)

GIでTTRの欠点を克服できるか?

myGI(ns501.data)
myGI(ns502.data)
myGI(ns502.data)
myGI(ns503.data)
myGI(ns504.data)
myGI(ns505.data)
myGI(ns506.data)
myGI(ns507.data)
myGI(ns508.data)
myGI(ns509.data)
myGI(ns510.data)
  • 同じことを何度も繰り返すのはめんどくさい。=> 複数のファイルに対して繰り返し自動的に実行する
  • 同じ処理を、ファイル一覧のすべてのファイルに対して、繰り返すようにする。

繰返し処理(制御:プログラムの流れのコントロール)

for (条件) {
        すること
        すること
}

条件の書き方: 変数 in その範囲

例: i in 1:19

  1から19まで、順に i に入れる

ファイル一覧の取得: list.files()

  • カレントディレクトリー内のファイル一覧の取得
  • 事前に目的とするディレクトリー(フォルダー)内に移動しておくこと
files <- list.files()

例: i in files

  filesの中の個々のファイルを、順に i に入れる

フォルダー内のすべてのファイルのGIを出す

すること

  1. myData() でファイルを読み込みデータ化
  2. myGI() でGIを出す
  3. 一つにまとめる
myGI(myData())

スクリプトにまとめる

myData <- function(){
  lines.tmp <- scan(choose.files(), what="char", sep="\n")
  body.tmp <- grep("^\\*\\w+:\t", lines.tmp, value=T)
  data.tmp <- gsub("^\\*\\w+:\t", "", body.tmp)
  data.tmp <- data.tmp[data.tmp != ""]
}

myGI <- function(d){
  tmp4 <- gsub("[[:punct:]]", " ", d)
  tmp5 <- gsub("  +", " ", tmp4)
  tmp6 <- tolower(tmp5)
  tmp7 <- strsplit(tmp6, " ")
  tmp8 <- unlist(tmp7)
  token <- sort(tmp8)
  type <- unique(token)
# length(type)/length(token)
  length(type)/sqrt(length(token))
}
myGI2 <- function(){
# myData部分
  lines.tmp <- scan(choose.files(), what="char", sep="\n")
  body.tmp <- grep("^\\*\\w+:\t", lines.tmp, value=T)
  data.tmp <- gsub("^\\*\\w+:\t", "", body.tmp)
  data.tmp <- data.tmp[data.tmp != ""]

# myGI部分
# tmp4 <- gsub("[[:punct:]]", " ", d)
  tmp4 <- gsub("[[:punct:]]", " ", data.tmp)  # 上のmyData部分の結果data.tmpを受けて処理する
  tmp5 <- gsub("  +", " ", tmp4)
  tmp6 <- tolower(tmp5)
  tmp7 <- strsplit(tmp6, " ")
  tmp8 <- unlist(tmp7)
  token <- sort(tmp8)
  type <- unique(token)
# length(type)/length(token)
  length(type)/sqrt(length(token))
}
setwd("NICER1_3/NICER_NS")

myGI2()
## [1] 13.1793
  • ただし、これだと、いちいち窓を開いてファイルを選ぶ必要がある。
  • したいのは、ファイル一覧のファイルを指定して処理すること。

myGI2() の修正

  • function() を function(F)として、「オブジェクト」を指定して実行するように
  • choose.files()を 指定されたオブジェクトに置き換える
myGI2F <- function(F){
# myData部分
# lines.tmp <- scan(choose.files(), what="char", sep="\n") # choose.files()をやめて
  lines.tmp <- scan(F, what="char", sep="\n")              # function(F)で指定したものを処理対象に
  body.tmp <- grep("^\\*\\w+:\t", lines.tmp, value=T)
  data.tmp <- gsub("^\\*\\w+:\t", "", body.tmp)
  data.tmp <- data.tmp[data.tmp != ""]

# myGI部分
# tmp4 <- gsub("[[:punct:]]", " ", d)
  tmp4 <- gsub("[[:punct:]]", " ", data.tmp)
  tmp5 <- gsub("  +", " ", tmp4)
  tmp6 <- tolower(tmp5)
  tmp7 <- strsplit(tmp6, " ")
  tmp8 <- unlist(tmp7)
  token <- sort(tmp8)
  type <- unique(token)
# length(type)/length(token)
  length(type)/sqrt(length(token))
}

繰り返し処理

setwd("NICER1_3/NICER_NS")

files <- list.files()
for (i in files) {
  gi <- myGI2F(i)
  cat(gi, "\n")               # for のなかに命令を入れる場合、明示的にcat()で結果を出力するようにする
                              # "\n" を付けて出力の際に「改行」する。
}

この処理自体を独自関数にまとめる:myGIfiles()

myGIfiles <- function(){
  
  files <- list.files()
  for (i in files) {
    
   gi <- myGI2F(i)
   
   cat(gi, "\n")
  }

}

実行

setwd("NICER1_3/NICER_NS")

myGIfiles()

myGIfilesの中身は以下と同じ

myGIfiles2 <- function(){
  
  files <- list.files()
  for (i in files) {

    # myData部分
# lines.tmp <- scan(choose.files(), what="char", sep="\n")
  lines.tmp <- scan(i, what="char", sep="\n")                   # オブジェクトを i に合わせる
  body.tmp <- grep("^\\*\\w+:\t", lines.tmp, value=T)
  data.tmp <- gsub("^\\*\\w+:\t", "", body.tmp)
  data.tmp <- data.tmp[data.tmp != ""]           

# myGI部分
# tmp4 <- gsub("[[:punct:]]", " ", d)
  tmp4 <- gsub("[[:punct:]]", " ", data.tmp) 
  tmp5 <- gsub("  +", " ", tmp4)
  tmp6 <- tolower(tmp5)
  tmp7 <- strsplit(tmp6, " ")
  tmp8 <- unlist(tmp7)
  token <- sort(tmp8)
  type <- unique(token)
# length(type)/length(token)
# length(type)/sqrt(length(token))
    
   gi <- length(type)/sqrt(length(token))        # 結果の部分を gi に入れる
   
   cat(gi, "\n")
  }

}

実行

setwd("NICER1_3/NICER_NS")


myGIfiles2()

♪ 楽しい演習

演習1:ディレクトリー内のすべてのファイルのTTRが出るプログラム myTTRfiles() を作ってみよう。

(^^♪ 解答例

myTTRfiles <- function(){
  
  files <- list.files()
  for (i in files) {

    # myData部分
# lines.tmp <- scan(choose.files(), what="char", sep="\n")
  lines.tmp <- scan(i, what="char", sep="\n")                   # オブジェクトを i に合わせる
  body.tmp <- grep("^\\*\\w+:\t", lines.tmp, value=T)
  data.tmp <- gsub("^\\*\\w+:\t", "", body.tmp)
  data.tmp <- data.tmp[data.tmp != ""]           

# myGI部分
# tmp4 <- gsub("[[:punct:]]", " ", d)
  tmp4 <- gsub("[[:punct:]]", " ", data.tmp) 
  tmp5 <- gsub("  +", " ", tmp4)
  tmp6 <- tolower(tmp5)
  tmp7 <- strsplit(tmp6, " ")
  tmp8 <- unlist(tmp7)
  token <- sort(tmp8)
  type <- unique(token)
# length(type)/length(token)
# length(type)/sqrt(length(token))
    
   ttr <- length(type)/length(token)        # ここを修正
   
   cat(ttr, "\n")
  }

}

実行

setwd("NICER1_3/NICER_NS")

myTTRfiles()

演習2:ディレクトリー内のすべてのファイルのType, Token, TTR, GI が出るプログラム myVoc() を作ってみよう。

(^^♪ 解答例

myVoc <- function(){
  files <- list.files()
  for (i in files) {
    lines.tmp <- scan(i, what="char", sep="\n")
    body.tmp <- grep("^\\*\\w+:\t", lines.tmp, value=T)
    data.tmp <- gsub("^\\*\\w+:\t", "", body.tmp)
    data.tmp <- data.tmp[data.tmp != ""]
    tmp4 <- gsub("[[:punct:]]", " ", data.tmp) 
    tmp5 <- gsub("  +", " ", tmp4)
    tmp6 <- tolower(tmp5)
    tmp7 <- strsplit(tmp6, " ")
    tmp8 <- unlist(tmp7)
    token <- sort(tmp8)
    type <- unique(token)
    ttr <- length(type)/length(token)
    gi  <- length(type)/sqrt(length(token))
   
   cat(length(type), length(token), ttr, gi, "\n")
  }

}

実行

setwd("NICER1_3/NICER_NS")

myVoc()

演習3:ギローインデックスはTTRの問題を解決しただろうか?


平均単語長(Average Word Length):myAWL()

「長い単語は難しい」

  • 単語を構成する文字数の平均
  • 単語数と文字数とが分かれば、平均が計算できる。(総文字数÷総単語数=平均文字数)
  • 単語数は Token
  • 文字数は?

文字数を数えるコマンド(関数): nchar()

nchar("internationalization")
## [1] 20
  • ファイルに含まれる総文字数
  • 文字以外のスペースなども文章には含まれている
  • コンピューターは、スペースも「文字」として数えてしまう。
nchar("two words")
## [1] 9
  • スペースを除く
nchar("twowords")
## [1] 8

要素をつなげる便利なコマンド:paste(変数, collapse=“つなげる文字”)

  • つなげる文字を "" とすることで、「削除」になる

すでに単語のリストは作成可能:各要素が単語のリスト

words <- c("two", "words")

paste(words, collapse="")
## [1] "twowords"

例:ns502.data に本文部分が入っているとして

文字数を数えてみる

token <- unlist(strsplit(ns502.data, "\\W"))
tmp   <- paste(token, collapse = "")
nchar(tmp)

文字数を単語数で割ってAWLを出す

myAWL <- function(d){
  token <- unlist(strsplit(d, "\\W"))
  tmp   <- paste(token, collapse = "")
  nchar(tmp)/length(token)
}
myAWL(ns502.data)

平均文長(Average Sentence Length):myASL()

「長い文は難しい」

  • 文を構成する単語数の平均
  • 総単語数÷総文数=平均単語数=平均文長)
  • 単語数は Token
  • 文数は? ** 文の数=文を要素としたデータの要素数(例:length(ns502.data)
length(ns502.data)

単語数を文数で割ってASLを出す

myASL <- function(d){
  
  token <- unlist(strsplit(d, "\\W"))
  length(token)/length(d)
  
}
myASL(ns502.data)

文章の難しさ:難しい単語+長い文

0.39(語数/文数)+11.8(シラブル数/語数)-15.59

二つの指標を合わせて独自の文章の難しさ指標を作ってみる

myRD <- function(d){
  
  token <- unlist(strsplit(d, "\\W"))
  tmp   <- paste(tmp, collapse = "")
  awl <- nchar(tmp)/length(token)
  
  asl <-  length(token)/length(d)
  
  0.39*asl + 11.8*awl - 15.59
}
myRD(ns502.data)

課題

フォルダー内のすべてのファイルのType・Token・TTR・GI・AWL・ASL を一度に出力するプログラムを作ってみよう。

  • 画面に結果が出力されるところまででよいです。

  • 四捨五入のコマンドは round() ** 小数点以下3桁目を四捨五入して2ケタまでだすには、round(変数, digits = 2)

(^^♪ 解答例

myIndexes <- function(){
  files <- list.files()
  for (i in files) {
    lines.tmp <- scan(i, what="char", sep="\n")
    body.tmp <- grep("^\\*\\w+:\t", lines.tmp, value=T)
    data.tmp <- gsub("^\\*\\w+:\t", "", body.tmp)
    data.tmp <- data.tmp[data.tmp != ""]
    tmp4 <- gsub("[[:punct:]]", " ", data.tmp) 
    tmp5 <- gsub("  +", " ", tmp4)
    tmp6 <- tolower(tmp5)
    tmp7 <- strsplit(tmp6, " ")
    tmp8 <- unlist(tmp7)
    token <- sort(tmp8)
    type <- unique(token)
    ttr <- length(type)/length(token)
    gi  <- length(type)/sqrt(length(token))
    
    tmp   <- paste(token, collapse = "")
    awl <- nchar(tmp)/length(token)
   
    asl <- length(token)/length(data.tmp)
  
    
   cat(length(type), length(token), ttr, gi, awl, asl,"\n")
  }

}

実行

setwd("NICER1_3/NICER_NS")

myIndexes()