Lecture5: Manipulate関数

getFreq2015.Rを読み込む

source("getFreq2015.R")
単語頻度数分布
res<-getFreq2015("osaka-u.txt")

補足:lapply():listへの関数の適用

単語の文字数を調べる

nchar(res$term[1])
## [1] 3

リスト内の要素すべてに適用

lapply(res$term, nchar)
## [[1]]
## [1] 3
## 
## [[2]]
## [1] 3
## 
## [[3]]
## [1] 2
unlist(lapply(res$term, nchar))
## [1] 3 3 2

Zipf’sの法則:ランク個別の計算例

\[Frequency=\frac{K}{Rank^A} \] K,A: 定数

K=as.numeric(res[1,2])
A=0.75

Rank1

rank1 <- seq(1:dim(res)[1])[1]
rank1
## [1] 1
K/rank1^A
## [1] 33

Rank2

rank2 <- seq(1:dim(res)[1])[2]
K/rank2^A
## [1] 19.62192

全てのrankに適用

lapply(rank, function(r) K/r^A)
## [[1]]
## [1] 33
## 
## [[2]]
## [1] 19.62192
## 
## [[3]]
## [1] 14.47681

1つのリストにまとめる

unlist(lapply(rank, function(r) K/r^A))
## [1] 33.00000 19.62192 14.47681

Zipf’sの法則

\[Frequency=\frac{K}{Rank^A} \] K,A: 定数

K=as.numeric(res[1,2])
A=0.75
K
## [1] 33
rank <- seq(1:dim(res)[1])
zipf <- unlist(lapply(rank, function(r) K/r^A))

manipulate package

インタラクティブなプロット

library(manipulate)

Zipfs理論値の色の選択

picker()関数

title="Zipf's Law"
xlabel="Rank"
ylabel="Frequency"

manipulate(
  {
    plot(zipf, log="xy", type="l",col=zipfsColors ,
    xlim=c(1,nrow(res)),ylim=c(1,100),main=title, xlab=xlabel, ylab=ylabel)
    par(new=T)
    plot(rownames(res),res[,2], xlim=c(1,nrow(res)), ylim=c(1,100),log="xy",pch=8, col="darkgreen", main=title, xlab=xlabel, ylab=ylabel)
    legend("topright",c("Frequency","Zipf's law"),lty=c(NA,1),pch=c(8,NA),col=c("darkgreen",col=zipfsColors))
  }
, zipfsColors=picker("red", "yellow", "green", "violet", "orange", "blue", "pink", "cyan") 
)

実習1

実際の値(*プロット)の色を選べるように変えてください。 初期値の色は“darkgreen”を指定 alt text

スライダー:定数Kの値を変化させる

title="Zipf's Law"
xlabel="Rank"
ylabel="Frequency"

K=as.numeric(res[1,2])
A=0.75

rank <- seq(1:dim(res)[1])

manipulate(
  {
    zipf <- unlist(lapply(rank, function(r) constK/r^A))
    plot(zipf, log="xy", type="l",col="red" ,
    xlim=c(1,nrow(res)),ylim=c(1,100),main=title, xlab=xlabel, ylab=ylabel)
    par(new=T)
    plot(rownames(res),res[,2], xlim=c(1,nrow(res)), ylim=c(1,100),log="xy",pch=8, col="darkgreen", main=title, xlab=xlabel, ylab=ylabel)
    legend("topright",c("Frequency","Zipf's law"),lty=c(NA,1),pch=c(8,NA),col=c(col="darkgreen",col="red"))
    text(5, 85, "Frequency=K/Rank^A")
    text(5, 70, paste("K=", constK))
    text(5, 60, paste("A=", A))
  }
, constK=slider(10,100, initial=res[1,2],step=2)
)

実習2:定数Aの値を変化させる

alt text


同一ディレクトリの複数フォルダから出現単語行列を作成する

ディレクトリ名

dirName <- "testData"

指定ディレクトリのファイル一覧を取得

files <- list.files(dirName)
files
## [1] "test1.txt" "test2.txt" "test3.txt"

作業ディレクトリからのファイルの相対参照パスを作成

filesDir <- unlist(lapply(dirName, paste, files, sep = "/"))
filesDir
## [1] "testData/test1.txt" "testData/test2.txt" "testData/test3.txt"

ファイルリストからの素頻度表作成

freqLst <- lapply(filesDir, getFreq2015)
freqLst
## [[1]]
##   term test1
## 1    c    13
## 2    e     7
## 3    b     4
## 4    a     3
## 
## [[2]]
##   term test2
## 1    f    11
## 2    g     7
## 3    b     4
## 4    a     2
## 5    c     2
## 6    e     1
## 
## [[3]]
##   term test3
## 1    f     9
## 2    g     7
## 3    h     4
## 4    c     3
## 5    a     2
## 6    d     1
## 7    e     1

補足:ファイルリストからの相対頻度表作成

lapply(filesDir, getFreq2015, relative=TRUE)
## [[1]]
##   term test1
## 1    c 0.481
## 2    e 0.259
## 3    b 0.148
## 4    a 0.111
## 
## [[2]]
##   term test2
## 1    f 0.407
## 2    g 0.259
## 3    b 0.148
## 4    a 0.074
## 5    c 0.074
## 6    e 0.037
## 
## [[3]]
##   term test3
## 1    f 0.333
## 2    g 0.259
## 3    h 0.148
## 4    c 0.111
## 5    a 0.074
## 6    d 0.037
## 7    e 0.037

データの結合

freqLst最初の要素をmtxに代入

freqLst[[1]]
##   term test1
## 1    c    13
## 2    e     7
## 3    b     4
## 4    a     3
mtx <- freqLst[[1]]

mtxの残り(1つ目のファイル以外)のリスト freqLst[-1]

freqLst[-1]
## [[1]]
##   term test2
## 1    f    11
## 2    g     7
## 3    b     4
## 4    a     2
## 5    c     2
## 6    e     1
## 
## [[2]]
##   term test3
## 1    f     9
## 2    g     7
## 3    h     4
## 4    c     3
## 5    a     2
## 6    d     1
## 7    e     1

mtxの残りのリスト freqLst[-1] をfor文でmerge

for (i in freqLst[-1]) mtx <- merge(mtx, i, all = T, by = "term")
mtx
##   term test1 test2 test3
## 1    a     3     2     2
## 2    b     4     4    NA
## 3    c    13     2     3
## 4    d    NA    NA     1
## 5    e     7     1     1
## 6    f    NA    11     9
## 7    g    NA     7     7
## 8    h    NA    NA     4

欠損値(NA)を0に変更

mtx[is.na(mtx)] <- 0

アルファベッド順で並べ替え

mtx <- mtx[order(as.vector(mtx$term)), ]
mtx
##   term test1 test2 test3
## 1    a     3     2     2
## 2    b     4     4     0
## 3    c    13     2     3
## 4    d     0     0     1
## 5    e     7     1     1
## 6    f     0    11     9
## 7    g     0     7     7
## 8    h     0     0     4

行名にmtxの1列目を代入

row.names(mtx) <- mtx[, 1]
mtx
##   term test1 test2 test3
## a    a     3     2     2
## b    b     4     4     0
## c    c    13     2     3
## d    d     0     0     1
## e    e     7     1     1
## f    f     0    11     9
## g    g     0     7     7
## h    h     0     0     4

mtxの1列目のデータを削除

mtx <- mtx[-1]
mtx
##   test1 test2 test3
## a     3     2     2
## b     4     4     0
## c    13     2     3
## d     0     0     1
## e     7     1     1
## f     0    11     9
## g     0     7     7
## h     0     0     4

今日の課題(締め切り12月1日)

課題:同一ディレクトリ内の複数テキストファイルの頻度表を出力する関数を作成しなさい。

関数名:getFreqDir

引数1:ディレクトリ名

引数2(オプション引数):頻度タイプ

オプション引数値により素頻度行列、相対頻度行列を返す関数を作成しなさい。

ただし、オプション引数のデフォルトは、素頻度行列が結果として出力されること。

ヒント:getFreq2015の関数を利用

使用例1:“testData”ディレクトリ内の粗頻度行列

source("getFreqDir.R")
getFreqDir("testData")
##   test1 test2 test3
## a     3     2     2
## b     4     4     0
## c    13     2     3
## d     0     0     1
## e     7     1     1
## f     0    11     9
## g     0     7     7
## h     0     0     4

使用例1:“testData”ディレクトリ内の相対頻度行列

getFreqDir("testData" ,relative=TRUE)
##   test1 test2 test3
## a 0.111 0.074 0.074
## b 0.148 0.148 0.000
## c 0.481 0.074 0.111
## d 0.000 0.000 0.037
## e 0.259 0.037 0.037
## f 0.000 0.407 0.333
## g 0.000 0.259 0.259
## h 0.000 0.000 0.148