R_Data_Manipulation

1505 days ago by takepwave

# RとPandasのデータフレームを相互に変換する関数を読み込む # Rの必要なライブラリ r('library(ggplot2)') r('library(jsonlite)') # RUtilの読み込み load(DATA + 'RUtil.py') 
       
# 日本語を含むリストを一行でプリントする import json def _plist(obj): if isinstance(obj, list): sys.stdout.write("[") for i in range(len(obj)): if i != 0: sys.stdout.write(", ") orig = json.dumps(obj[i], indent=4) sys.stdout.write(eval("u'''%s'''" % orig).encode('utf-8')) sys.stdout.write("]\n") 
       

来るデータ分析のために「Rデータ自由自在」を読んでいます。

2.11 「表計算データ」からのメモ

集計データをExcelで管理している人は多いと思いますので、RでExcelのシートを読み込む方法をSageでも試してみます。

使用するデータは、http://www.pwv.co.jp/data/test.xlsです。

#r('install.packages("gdata")') r('library(gdata)') 
       
 [1] "gdata"     "jsonlite"  "ggplot2"   "stats"     "graphics" 
"grDevices" "utils"     "datasets" 
 [9] "methods"   "base"     
 [1] "gdata"     "jsonlite"  "ggplot2"   "stats"     "graphics"  "grDevices" "utils"     "datasets" 
 [9] "methods"   "base"     

test.xlsの内容は以下の通りです。

r('tbl <- read.xls("http://www.pwv.co.jp/data/test.xls", sheet=1)') r('tbl') 
       
  a b c
1 1 2 a
2 3 4 b
  a b c
1 1 2 a
2 3 4 b

3.4 DBIパッケージ(データベースへのアクセス)

RではDBIというデータベースにアクセスするための共通インターフェースが提供されており、MySQL, SQLiteもサポートしています。

以下では、ローカルのマシンで作成した日経サイトの記事のタイトルのデータベース(一部)をRを使って以下の手順でSQLiteに移行したものを使用しました。

> library(RMySQL)
> drv = dbDriver("MySQL")
> con = dbConnect(drv, dbname='nikkeidb', user='test', password='test2012', host='localhost')
> dbGetQuery(con, 'SELECT * FROM nikkei_news LIMIT 10;')
   id                                                            title
1   1                 キヤノン、1~6月期純利益4%増 タイの生産回復
2   2                                   日経JAPAN1000大引け、続落
3   3                         ファナック、純利益2%増 海外販売が好調
4   4                     KDDI、純利益29%減 スマホ割引で通信料減
5   5             新興株25日、ジャスダック7日続落 主力銘柄に換金売り
6   6         山口副総裁、海外経済「回復はそう遠くない将来に実現する」
> summary(result)
       id           title             news_url           pub_date        
 Min.   : 1.00   Length:10          Length:10          Length:10         
 1st Qu.: 3.25   Class :character   Class :character   Class :character  
 Median : 5.50   Mode  :character   Mode  :character   Mode  :character  
 Mean   : 5.50                                                           
 3rd Qu.: 7.75                                                           
 Max.   :10.00                                                          

> library(RMySQL)

> drv <- dbDriver("MySQL")

> con <- dbConnect(drv, dbname='nikkeidb', user='test', password='test2012', host='localhost')

> result <- dbGetQuery(con, 'SELECT * FROM nikkei_news LIMIT 10;')

dbWriteTableを使ってSQLiteに挿入する

> library(RSQLite)

> drv2 = dbDriver("SQLite")

> con2 = dbConnect(drv2, "/Users/take/Desktop/testdb")

> rs = dbSendQuery(con2, "CREATE TABLE nikkei_news (id INTEGER, title TEXT, news_url TEXT, pub_date DATE)")

> rs = dbWriteTable(con2, "nikkei_news", result, append=T, row.names=F)

> dbDisconnect(con2)

#r('install.packages("RSQLite")') r('library(RSQLite)') 
       
 [1] "RSQLite"   "DBI"       "gdata"     "jsonlite"  "ggplot2"   "stats"
"graphics"  "grDevices"
 [9] "utils"     "datasets"  "methods"   "base"     
 [1] "RSQLite"   "DBI"       "gdata"     "jsonlite"  "ggplot2"   "stats"     "graphics"  "grDevices"
 [9] "utils"     "datasets"  "methods"   "base"     
db_path = DATA + 'testdb' r('drv <- dbDriver("SQLite")') r('con<- dbConnect(drv, "%s")' % db_path) 
       
<SQLiteConnection>
<SQLiteConnection>

残念ながら、出力に含まれる日本語は、Sageでは\nnnの8進で表示されてしまいます。

print r('dbGetQuery(con, "SELECT * FROM nikkei_news LIMIT 2;")') 
       
  id                                            title
1  1 キヤノン、1~6月期純利益4%増 タイの生産回復
2  2                   日経JAPAN1000大引け、続落
                                                     news_url   pub_date
1 http://www.nikkei.com/article/DGXNASFL250F1_V20C12A7000000/ 2012-07-25
2 http://www.nikkei.com/article/DGXNASFL250FU_V20C12A7000000/ 2012-07-25
  id                                            title
1  1 キヤノン、1~6月期純利益4%増 タイの生産回復
2  2                   日経JAPAN1000大引け、続落
                                                     news_url   pub_date
1 http://www.nikkei.com/article/DGXNASFL250F1_V20C12A7000000/ 2012-07-25
2 http://www.nikkei.com/article/DGXNASFL250FU_V20C12A7000000/ 2012-07-25

SageでSQLiteのデータベースを使う

今度は、Sageで直接testdbにアクセスしてみます。

# Rで作成したデータベースをSageで使う import sqlite3 con = sqlite3.connect(db_path) 
       
cur = con.execute("SELECT * FROM nikkei_news LIMIT 3;") 
       

Sageでもフェッチした結果を表示するとunicodeで取り出され、文字化けしてしまいます。

rs = cur.fetchone() print rs 
       
(1,
u'\u30ad\u30e4\u30ce\u30f3\u3001\uff11\uff5e\uff16\u6708\u671f\u7d14\u52\
29\u76ca\uff14\uff05\u5897\u3000\u30bf\u30a4\u306e\u751f\u7523\u56de\u5f\
a9', u'http://www.nikkei.com/article/DGXNASFL250F1_V20C12A7000000/',
u'2012-07-25')
(1, u'\u30ad\u30e4\u30ce\u30f3\u3001\uff11\uff5e\uff16\u6708\u671f\u7d14\u5229\u76ca\uff14\uff05\u5897\u3000\u30bf\u30a4\u306e\u751f\u7523\u56de\u5fa9', u'http://www.nikkei.com/article/DGXNASFL250F1_V20C12A7000000/', u'2012-07-25')

文字化けした部分を取り出し、str関数で文字列に変換してprintとすると正しく表示できます。

print str(rs[1]) 
       
キヤノン、1~6月期純利益4%増 タイの生産回復
キヤノン、1~6月期純利益4%増 タイの生産回復
rs = cur.fetchall(); print rs 
       
[(2,
u'\u65e5\u7d4c\uff2a\uff21\uff30\uff21\uff2e1000\u5927\u5f15\u3051\u3001\
\u7d9a\u843d',
u'http://www.nikkei.com/article/DGXNASFL250FU_V20C12A7000000/',
u'2012-07-25'), (3,
u'\u30d5\u30a1\u30ca\u30c3\u30af\u3001\u7d14\u5229\u76ca\uff12\uff05\u58\
97\u3000\u6d77\u5916\u8ca9\u58f2\u304c\u597d\u8abf',
u'http://www.nikkei.com/article/DGXNASFL250FQ_V20C12A7000000/',
u'2012-07-25')]
[(2, u'\u65e5\u7d4c\uff2a\uff21\uff30\uff21\uff2e1000\u5927\u5f15\u3051\u3001\u7d9a\u843d', u'http://www.nikkei.com/article/DGXNASFL250FU_V20C12A7000000/', u'2012-07-25'), (3, u'\u30d5\u30a1\u30ca\u30c3\u30af\u3001\u7d14\u5229\u76ca\uff12\uff05\u5897\u3000\u6d77\u5916\u8ca9\u58f2\u304c\u597d\u8abf', u'http://www.nikkei.com/article/DGXNASFL250FQ_V20C12A7000000/', u'2012-07-25')]

そこで、Yahooで使った日本語を含んだリストを1行に表示する関数_plistを使って、

検索結果を以下の様に出力することにしました。

for i in rs: _plist(list(i)) 
       
[2, "日経JAPAN1000大引け、続落",
"http://www.nikkei.com/article/DGXNASFL250FU_V20C12A7000000/",
"2012-07-25"]
[3, "ファナック、純利益2%増 海外販売が好調",
"http://www.nikkei.com/article/DGXNASFL250FQ_V20C12A7000000/",
"2012-07-25"]
[2, "日経JAPAN1000大引け、続落", "http://www.nikkei.com/article/DGXNASFL250FU_V20C12A7000000/", "2012-07-25"]
[3, "ファナック、純利益2%増 海外販売が好調", "http://www.nikkei.com/article/DGXNASFL250FQ_V20C12A7000000/", "2012-07-25"]