Ruby側の正規表現で記号っぽい文字を取り除くことにした。あんま変わってない。あとはhtmlっぽいところがまだ入ってくるので、その辺は自分でフィルタをかけないとだめだな。
extract_meisi_from_blog <- function(url){ ruby <- paste(" require %q[rubygems] require %q[open-uri] require %q[hpricot] require %q[MeCab] require %q[kconv] url = %q[",url,"] description = %q[] begin doc = Hpricot(open(url).read) rescue => ex exit end (doc/:item).each {|item| description = description + (item/:description).inner_text } begin c = MeCab::Tagger.new(%q[-Ochasen]) n = c.parseToNode(description) list = Array.new while n do f = n.feature.split(/,/) if /名詞/ =~ f[0] if /([0-9A-Za-z_ぁ-んァ-ヴ一-龠]){2,}/ =~ n.surface list.push(n.surface) end end n = n.next end list.each{|x| puts x} rescue exit end ",sep="") return(system(paste("echo '",ruby,"'"," | /opt/local/bin/ruby ",sep=""),intern=TRUE)) }
これをとりあえずこんな感じでつめこめばいいかな。
> head(hoge) words V2 V3 V4 1 class 514 21 56 2 cgi 481 1 0 3 span 451 18 26 4 theta 336 0 0 5 hatena 304 10 118 6 http 293 69 130 > summary(hoge) words V2 V3 V4 Length:2895 Min. : 0.000 Min. : 0.000 Min. : 0.000 Class :AsIs 1st Qu.: 0.000 1st Qu.: 0.000 1st Qu.: 0.000 Mode :character Median : 0.000 Median : 0.000 Median : 0.000 Mean : 3.344 Mean : 1.215 Mean : 1.759 3rd Qu.: 1.000 3rd Qu.: 1.000 3rd Qu.: 1.000 Max. :514.000 Max. :519.000 Max. :224.000
どんどんdata.frameにbindしていくつもりだったんだけど、挫折した。結局、listの要素にベクトルを持たせるという感じになっている。
> str(a) List of 3 $ : int [, 1:1041] 514 481 451 336 304 293 290 290 248 245 ... ..- attr(*, "dimnames")=List of 1 .. ..$ : chr [1:1041] "class" "cgi" "span" "theta" ... $ : int [, 1:1009] 519 69 46 44 39 32 30 28 26 25 ... ..- attr(*, "dimnames")=List of 1 .. ..$ : chr [1:1009] "br" "http" "com" "href" ... $ : int [, 1:1388] 224 130 126 124 118 117 109 98 80 79 ... ..- attr(*, "dimnames")=List of 1 .. ..$ : chr [1:1388] "li" "http" "ul" "br" ...
a <- list() for(url in c("http://d.hatena.ne.jp/syou6162/rss2","http://blog.isocchi.com/rss.xml","http://d.hatena.ne.jp/Hash/rss2")){ cat(url,fill=T) word <- table(extract_meisi_from_blog(url)) b <- list(word[order(word,decreasing=TRUE)]) a <- append(a,b) } hoge <- data.frame(words=I(unique(unlist(mapply(names,a))))) for(i in seq(length(a))){ hoge[,i+1] <- as.numeric(mapply(function(x){ifelse(!is.na(a[[i]][x]),a[[i]][x],0)},hoge$words)) }
たぶん後のほうでは、行列に近い形のほうが扱いやすいような気がするので、整形しておく。
#keywordをrow.namesにして、データフレームから出しておく row.names(hoge) <- hoge$words hoge$words <- NULL #colのnameのほうはblogのurlにしておく names(hoge) <- as.character(get_blogs_from_opml()$V2)[1:20]
すると、as.matrixをすぐにでもできる形になっている。
> head(hoge[,1:3]) http://totodaisuke.weblogs.jp/blog/atom.xml の 0 Perl 0 http 0 Apache 0 jp 0 ん 0 http://feeds.feedburner.jp/shebang http://svslab.jp/0x0a/index.rdf の 9 7 Perl 5 0 http 5 0 Apache 4 0 jp 4 0 ん 4 0
feedのtypeがatomになっているやつは行列に入っている数字が全部0とかいうことになっているので*1、そこははぶいたりする。applyかわいい。
hoge <- hoge[,as.vector(apply(hoge,2,function(x){!all(x == 0)}))]
*1:スクレイピングのところをrss形式でしか処理していないから