2022-09-07 使い方の改善。setwd()、getwd()
2020-11-23 Rパッケージ化
やりたい事
法人税の決算作業で「受取配当金を集計する」のですが、SBI証券の場合、元ネタがPDF形式なのですよ。
↓サンプル
昔はこのPDFを見て転記(手入力)してた。
数枚(2〜3枚)だから、しょうがないな、と「割り切り」です。
だけど、
数十枚(10枚)を超えると、無理(むり)だよ!
自動化せねばならぬ。。
自動化するにはどうすればいいのか、
いくつかの言語(Pythonとか)のPDF関係のライブラリーを試した結果、
R言語のpdftoolsで対応する事としました。
#
使い方(パッケージ版)
githubにパッケージを作ったのでインストールしてください。
library(devtools) # install.packages("devtools")
install_github("nt1969m/sbitools",force=T) #面倒な事を聞かれたら、3: Noneで、
PDFのあるファイルパスを指定し、実行して下さい。
# setwd() ※PDFのあるディレクトリーを設定
# R本体の場合、 「メニュー」 → 「その他」 → 「作業ディレクトリの変更」
# RStudioの場合、「メニュー」→「Session」→「Set Working Directory」→「Choose Directory」
d <- getwd()
library(sbitools)
dummy <- Div(d) # 配当金の略語のつもり
CSVファイル"株式等配当金.csv"が作られたはず。
#
使い方(ソース直書き版)
※忘れてください。
銘柄名のみ全角で残し、残りを半角&型の調整
以下余白は削除
作業状況をファイル・ページ毎に出力します。
source( "B_0988_SBI証券_配当.R" )
# PDF群のディレクトリーを指定
d <- file.path( FY ,"B_0988_SBI証券/配当" )
#FY # 会計年度(Fiscal Year)のディレクトリ
配当 <- 配当.main( d )
write.table( 配当
,file.path( d ,"配当_会計.txt" ) ,sep="," )
# pdfデータをインポートするため
library( pdftools ) # install.packages( 'pdftools' )
library( stringi ) # install.packages("stringi")# 全角
配当.main <- function( d ) {
print( d )
files <- dir( d ,pattern = ".pdf$" ,ignore.case=T )
stack <- 配当.init()
for( a in files ) {
f <- file.path( d ,a ) # ファイル単位
# 入力
Pages <- pdf_info( f )$pages # 総ページ数
print( paste( a ,Pages ) )
mei <- 配当.pdf( pdf_data( f ) ,Pages )
stack <- rbind( stack ,mei )
}
return( 配当.fin( stack ) )
}
print( c("配当.main()" ,配当.main ) )
配当.pdf <- function( df ,Pages ) {
# 配当金
mei <- 配当.init()
for( p in 1:Pages ) {
mei[ p * 2 -1 ,] <- 配当.upper( df ,p )
mei[ p * 2 ,] <- 配当.lower( df ,p )
print( paste( " :" ,p ,substr( mei[ p * 2 -1,c(1:2) ] ,1 ,10 ) ,mei[ p * 2 ,c(1:2) ] ) )
}
return( mei )
}
print( c("配当.pdf()" ,配当.pdf ) )
配当.半角 <- function( mei ) {
# 半角
han <- 配当.init()
# stri_trans_nfkc( mei ) #NG
for( i in 1:nrow( mei ) ) {
han[ i ,1 ] <- mei [ i ,1 ]
han[ i ,-1 ] <- stri_trans_nfkc( mei [ i ,-1 ] )
}
han[ ,"お支払日"] <- as.Date( han[ ,"お支払日" ] ,format="%Y年%m月%d日")
han[ ,"配当基準日"] <- as.Date( han[ ,"配当基準日" ] ,format="%Y年%m月%d日")
return( han )
}
print( c("配当.半角()" ,配当.半角 ) )
配当.fin <- function( stack ) {
o <- ! is.na( stack[ ,"銘柄コード" ] ) # 以下余白を削除
h_mei <- 配当.半角( stack[ o, ] )
h_mei[ ,"銘柄名"] <- substr( h_mei[ ,"銘柄名" ] ,1 ,10 )
h_mei[ ,"銘柄コード"] <- gsub( "[()]" ,"" ,h_mei[ ,"銘柄コード"] )
h_mei[ ,"配当単価"] <- as.integer( gsub( "," ,"" ,h_mei[ ,"配当単価"] ) )
h_mei[ ,"数量"] <- as.integer( gsub( "," ,"" ,h_mei[ ,"数量"] ) )
h_mei[ ,"配当金額"] <- as.integer( gsub( "," ,"" ,h_mei[ ,"配当金額"] ) )
h_mei[ ,"所得税"] <- as.integer( gsub( "," ,"" ,h_mei[ ,"所得税"] ) )
h_mei[ ,"地方税"] <- as.integer( gsub( "," ,"" ,h_mei[ ,"地方税"] ) )
h_mei[ ,"端数処理代金"] <- as.integer( gsub( "," ,"" ,h_mei[ ,"端数処理代金"] ) )
h_mei[ ,"お受取金額"] <- as.integer( gsub( "," ,"" ,h_mei[ ,"お受取金額"] ) )
return( h_mei )
}
print( c("配当.fin()" ,配当.fin ) )
配当.init <- function() {
# 最終型
# 列数と列名を初期化
配当金 <- data.frame( matrix( NA ,0 ,11 ) )
colnames( 配当金 ) <- c(
"銘柄名" ,"銘柄コード"
,"お支払日" ,"配当単価" ,"数量"
,"配当金額" ,"所得税" ,"地方税" ,"端数処理代金" ,"お受取金額"
,"配当基準日" )
return( 配当金 )
}
print( c("配当.init()" ,配当.init ) )
# y抽出
配当.yn <- function( df ,p ,n ) {
# p:ページ
# n:明細行の"y"
x <- paste0( df[[ p ]]
[ df[[ p ] ]$"y" == n , ]$"x" )
x <- as.integer( x )
o <- order( c( x ) )
t <- paste0( df[[p] ]
[ df[[p] ]$"y" == n , ]$"text" )
return( t[ o ] )
}
print( c("配当.yn()" ,配当.yn ) )
# 日付の対処
配当.ymd <- function( ve ) {
d <- grep( "日" ,ve )
if( length( d ) != 1 ) return( ve ) # ベクトルの要素が「1」である事
y <- grep( "年" ,ve )
switch( d
, "1" = {
if( y == 1 ) {
paste0( ve[ d ] ) # 年月日
} else
paste0( ve[ y ] ,ve[ d ] ) # (月日) (年) ※欧米かよ
}
, "2" = paste0( ve[1] ,ve[ d ] ) # (年)月日 or (年月)日
, "3" = paste0( ve[1] ,ve[2] ,ve[ d ] ) # (年)(月)(日)
)
}
print( c("配当.ymd()" ,配当.ymd ) )
# 単価・数量の対処
配当.unit <- function( ve ) {
u <- grep( "." ,ve )
if( length( u ) != 1 ) return() # ベクトルの要素が「1」である事
return( c( ve[u] ,ve[u+1] ) ) # "配当単価" 、"数量"
}
print( c("配当.unit()" ,配当.unit ) )
# 銘柄コードの対処
配当.code <- function( ve ) {
n <- grep( ")" ,ve )
if( length( n ) != 1 ) return() # ベクトルの要素が「1」である事
switch( n
, "1" = paste0( ve[1] ) # "(NNNN)"
, "2" = paste0( ve[1] ,ve[2] ) # "(NNNN" ")" or "(" "NNNN)"
, "3" = paste0( ve[1] ,ve[2] ,ve[3] ) # "(" "NNNN" ")"
)
}
print( c("配当.code()" ,配当.code ) )
配当.name <- function( ve ) {
# 銘柄名の対処
switch( length( ve )
, "1" = paste( ve[ 1 ] ) # "X"
, "2" = paste( ve[ 1 ] ,ve[ 2 ] ) # "X" and"YY"
)
}
print( c("配当.name()" ,配当.name ) )
# 上段
配当.upper <- function( df ,p ) {
# p : ページ
y1 <- 配当.yn( df ,p ,91 )
y2 <- 配当.yn( df ,p ,100 )
y3 <- 配当.yn( df ,p ,94 )
y4 <- 配当.yn( df ,p ,126 )
y5 <- 配当.yn( df ,p ,139 )
y1 <- 配当.name( y1 ) # "X" と "YY" を結合
y2 <- 配当.code( y2 ) # "(nnnn" と ")" を結合
y3 <- c( 配当.ymd( y3 ) ,配当.unit( y3 ) )
y5 <- 配当.ymd(y5)
return( c( y1 ,y2 ,y3 ,y4 ,y5 ) )
}
print( c("配当.upper()" ,配当.upper ) )
# 下段
配当.lower <- function( df ,p ) {
# p : ページ
y6 <- 配当.yn( df ,p ,166 )
y7 <- 配当.yn( df ,p ,175 )
y8 <- 配当.yn( df ,p ,171 )
y9 <- 配当.yn( df ,p ,202 )
y10 <- 配当.yn( df ,p ,216 )
y6 <- 配当.name( y6 ) # "X" と "YY" を結合
y7 <- 配当.code( y7 )
y8 <- c( 配当.ymd( y8 ) ,配当.unit( y8 ) )
y10 <- 配当.ymd(y10)
# 返り値
r <- c( y6 ,y7 ,y8 ,y9 ,y10 )
n <- length( r )
if ( n != 11 ) {
return( c( r ,rep( NA ,11-n ) ) )
} else { # 明細行であれば
return( r )
}
}
print( c("配当.lower()" ,配当.lower ) )
#
pdftoolsとは
pdftools - CRAN
の、ようです。
まずはインストール
> library( pdftools ) # install.packages('pdftools')
警告メッセージ:
パッケージ ‘pdftools’ はバージョン 3.5.2 の R の下で造られました
感謝した記事
⭐️PDFの情報・文章をRでごっそり取得する https://www.google.com/url?sa=t&rct=j&q=&esrc=s&source=web&cd=&ved=2ahUKEwjJ9O7s4uTrAhUMMd4KHYmiAawQFjACegQIARAB&url=https%3A%2F%2Furibo.hatenablog.com%2Fentry%2F2016%2F02%2F27%2F195500&usg=AOvVaw0jOaR0QX2AbvggqgdelGAR#
PDFを分析
> f <-
file.path(
FY # 会計年度(Fiscal Year)のディレクトリ
,"B_0988_SBI証券/配当" # 中間のディレクトリ
,"なんちゃら.PDF" ) # ファイル名
> pdf_data( f )
[[1]]
# A tibble: 44 x 6
width height x y space text
<int> <int> <int> <int> <lgl> <chr>
1 14 6 482 10 FALSE 1/
2 28 6 518 10 FALSE 1ページ
3 64 6 460 19 TRUE 作成日:2020年
4 14 6 532 19 FALSE 6月
5 132 11 199 15 FALSE 株式等配当金のお知らせ
6 36 8 21 45 FALSE 有限会社
7 54 8 66 45 FALSE ○○○○○○○○
8 9 8 138 45 FALSE 様
9 21 6 273 64 FALSE Znn
10 79 6 28 91 FALSE SBIホールディングス
# … with 34 more rows
# 全部見たいので、テキスト出力
write.table(
pdf_data( f )
,gsub( ".PDF" ,".txt" ,f ) )
## ちなみに、地道に全部見るなら、こうなる。
pdf_data( f )[[1]][11:44,]
pdf_data( f )[[1]][21:44,]
pdf_data( f )[[1]][31:44,]
pdf_data( f )[[1]][41:44,]
"width" "height" "x" "y" "space" "text"
"1" 14 6 482 10 FALSE "1/"
"2" 28 6 518 10 FALSE "1ページ"
"3" 64 6 460 19 TRUE "作成日:2020年"
"4" 14 6 532 19 FALSE "6月"
"5" 132 11 199 15 FALSE "株式等配当金のお知らせ"
"6" 36 8 21 45 FALSE "有限会社"
"7" 54 8 66 45 FALSE "○○○○○○○○"
"8" 9 8 138 45 FALSE "様"
"9" 21 6 273 64 FALSE "Znn"
"10" 79 6 28 91 FALSE "SBIホールディングス"
"11" 36 6 36 100 FALSE "(8473"
"12" 7 6 86 100 FALSE ")"
"13" 43 6 86 126 FALSE "48,000"
"14" 14 6 554 19 FALSE "5日"
"15" 35 6 251 94 FALSE "2020年"
"16" 43 6 331 64 FALSE "726320"
"17" 14 6 295 94 FALSE "6月"
"18" 35 6 194 126 FALSE "7,351"
"19" 35 6 266 139 FALSE "2020年"
"20" 172 6 395 64 FALSE "nnnnnnnnnnnnnnnnnnnnnnnn"
"21" 14 6 316 94 FALSE "8日"
"22" 71 6 374 94 FALSE "80.0000000"
"23" 21 6 540 94 FALSE "600"
"24" 7 6 323 126 FALSE "0"
"25" 7 6 439 126 FALSE "0"
"26" 43 6 518 126 FALSE "40,649"
"27" 35 6 309 139 FALSE "3月31日"
"28" 28 6 28 171 FALSE "以下余白"
"29" 43 6 518 229 FALSE "40,649"
"30" 270 8 21 251 FALSE "◎端数処理代金につきましては、特定口座における譲渡所得等の計"
"31" 261 8 30 260 FALSE "算対象とはならないため確定申告が必要となる場合があります。"
"32" 252 8 30 269 FALSE "本お知らせは大切に保管していただき、確定申告時の手続きに"
"33" 189 8 30 278 FALSE "つきましては税務署等にお問い合わせ下さい。"
"34" 151 7 21 298 TRUE "nnnnnnnnnnnnnnnnnnnnn"
"35" 93 7 179 298 FALSE "xxxxxxxxxxxxx"
"36" 266 7 21 307 FALSE "nnnnnnnnnnnnSTWHABnnnP#ZNNnnnnnnnnnnn"
"37" 45 8 331 296 FALSE "(取引店)"
"38" 9 8 385 296 FALSE "イ"
"39" 9 8 403 296 FALSE "ン"
"40" 9 8 421 296 FALSE "タ"
"41" 9 8 439 296 FALSE "ー"
"42" 9 8 457 296 FALSE "ネ"
"43" 9 8 475 296 FALSE "ッ"
"44" 9 8 493 296 FALSE "ト"
#
テキスト抽出
欲しいテキストは下記の通り。
0 | 行1 | 行2 | 行3 | 行4 | 行5 |
---|---|---|---|---|---|
SBI記号→ | (nnnn) | (c) | (g) | ||
SBI列名→ | 銘柄名 | (銘柄コード) | お支払日 | 配当金額 | 配当基準日 |
y ↓ | あとで | 説明するが | 1頁 | 2明細 | だ |
上段 | 91 | 100 | 94 | 126 | 139 |
下段 | 166 | 175 | 171 | 202 | 216 |
##
xとy(3列と4列)
サンプル(なんちゃら.txt)の3列と4列が、
xとy、
これの意味するところは、テキスト(text)の表示位置かと。
下記↓表が見た目のイメージ。
位置 | テキスト | |
---|---|---|
x→ | 横の位置 | |
y↓ | ||
上段 | ||
91 | 銘柄名 | |
94 | お支払日、配当単価(A)、数量(B) | |
100 | (銘柄コード) | |
126 | 配当金額(税引前)(C)、所得税(D)、地方税(E)、端数処理代金(F)、お受取金額(G) | |
139 | 配当基準日 | |
下段 | 明細が無い場合 | |
166 | 銘柄名 | |
171 | 以下余白 | お支払日など |
175 | (銘柄コード) | |
202 | (C)等 | |
216 | 配当基準日 | |
縦の位置 |
##
y(4列)を頼りにテキストを抽出
冗長になるので、一旦(テンポラリー)dfという変数に保存。
# (前出)
write.table(
pdf_data( f )
,gsub( ".PDF" ,".txt" ,f ) )
# (前出)閉じる
df <- pdf_data( f )
# df:データフレーム(Data Frame)にコピー(名前は任意)
yごと(別、毎)にテキストを抽出
# y抽出
yn <- function( p ,n ) {
# p:ページ
# n:明細行の"y"
paste0(
df[ [p] ]
[ df[ [p] ]$"y" == n , ]$"text"
)
}
# 上段
y1 <- yn( 1 ,91 )
y2 <- yn( 1 ,100 )
y3 <- yn( 1 ,94 )
y4 <- yn( 1 ,126 )
y5 <- yn( 1 ,139 )
# 下段
y6 <- yn( 1 ,166 )
y7 <- yn( 1 ,175 )
y8 <- yn( 1 ,171 )
y9 <- yn( 1 ,202 )
y10 <- yn( 1 ,216 )
# 目検(目視にて検証)
> c( y1 ,y2 ,y3 ,y4 ,y5 )
[1] "SBIホールディングス" "(8473" ")"
[4] "2020年" "6月" "8日"
[7] "80.0000000" "600" "48,000"
[10] "7,351" "0" "0"
[13] "40,649" "2020年" "3月31日"
> c( y6 ,y7 ,y8 ,y9 ,y10 )
[1] "以下余白"
見づらいので、「日付」と「銘柄コード」を結合
# 日付の対処
ymd <- function( df ) {
# 「日」はどこにあるの?(要素数)
d <- grep( "日" ,df )
# ベクトルの要素が「1」である事
if( length( d ) != 1 ) return()
# 日付を表示するにも、いくつものパターン有り
switch( d
# 年月日
, "1" = paste0( df[1] )
# (年)月日 or (年月)日
, "2" = paste0( df[1] ,df[2] )
# (年)(月)(日)
, "3" = paste0( df[1] ,df[2] ,df[3] )
)
}
# 銘柄コードの対処
code <- function( df ) {
# 「)」はどこにあるの?(要素数)
n <- grep( ")" ,df )
# ベクトルの要素が「1」である事
if( length( n ) != 1 ) return() # 何もしない
switch( n
# "(NNNN)"
, "1" = paste0( df[1] )
# "(NNNN" ")" or "(" "NNNN)"
, "2" = paste0( df[1] ,df[2] )
# "(" "NNNN" ")"
, "3" = paste0( df[1] ,df[2] ,df[3] )
)
}
# 上段
y2 <- code( y2 ) # "(nnnn" と ")" を結合
y3 <- c( ymd( y3 ) ,tail( y3 ,2 ) )
y5 <- ymd(y5)
# 下段
if ( length( y6 ) != 0 ) {
# 下段が明細行であれば(以下余白では無い場合)
y7 <- code( y7 ) # "(nnnn" と ")" を結合
y8 <- c( ymd( y8 ) ,tail( y8 ,2 ) )
y10 <- ymd(y10)
}
> # 目検(目視にて検証)
> c( y1 ,y2 ,y3 ,y4 ,y5 )
[1] "SBIホールディングス" "(8473)" "2020年6月8日"
[4] "80.0000000" "600" "48,000"
[7] "7,351" "0" "0"
[10] "40,649" "2020年3月31日"
> c( y6 ,y7 ,y8 ,y9 ,y10 )
[1] "以下余白"
#
CSVを作りましょう!
mei <- data.frame( matrix(NA,0,11 )) # 列数のみ重要
# 列名、名前を書いときましょう。
colnames( mei ) <- c( "銘柄名" ,"銘柄コード"
,"お支払日" ,"配当単価" ,"数量"
,"配当金額" ,"所得税" ,"地方税" ,"端数処理代金" ,"お受取金額"
,"配当基準日" )
# 型ができたので、中身を入れる。
mei[ 1 , ] <- c( y1 ,y2 ,y3 ,y4 ,y5 )
# まずは上段、次は下段
if ( length(y6) == 0 ){
mei[ 2 , 1] <- y8 # 以下余白の場合
} else # 上段と同様に
mei[ 2 , ] <- c( y6 ,y7 ,y8 ,y9 ,y10 )
write.table( mei
,gsub( ".PDF" ,"_全角.txt" ,f )
)
"銘柄名" "銘柄コード" "お支払日" "配当単価" "数量" "配当金額" "所得税" "地方税" "端数処理代金" "お受取金額" "配当基準日"
"1" "SBIホールディングス" "(8473)" "2020年6月8日" "80.0000000" "600" "48,000" "7,351" "0" "0" "40,649" "2020年3月31日"
"2" "以下余白" NA NA NA NA NA NA NA NA NA NA
感謝した記事
Rでよくひっかかる、NAやlogical(0)、そのほかエラーの取り扱い https://yamakita.hatenablog.com/entry/20130111/1357867987#
全角という高い壁
アイム、ジャッパァニィズゥ! オゥケィ?
(I am Japanese! OK?)
日本人たるもの、
「全角」という高い壁を乗り越えねば、
「半角」とは戦えまい。
選択肢は2択
# 全角のパッケージ
# 〜ジ !
library( stringi ) # install.packages("stringi")
# 〜ガ !
library( stringr ) # install.packages("stringr")
選択 : 〜ジ
半角ヴァージョン(version)のCSVを作ります。
# 半角
h_mei <- mei
# stri_trans_nfkc( mei ) #NG
h_mei[1,] <- stri_trans_nfkc( mei [1, ] )
h_mei[2,] <- stri_trans_nfkc( mei [2, ] )
# 目検(目視にて検証)
> h_mei
銘柄名 銘柄コード お支払日 配当単価 数量 配当金額 所得税
1 SBIホールディングス (8473) 2020年6月8日 80.0000000 600 48,000 7,351
2 以下余白 <NA> <NA> <NA> <NA> <NA> <NA>
地方税 端数処理代金 お受取金額 配当基準日
1 0 0 40,649 2020年3月31日
2 <NA> <NA> <NA> <NA>
# 日付を変換
h_mei[ ,"お支払日"] <-
as.Date( h_mei[ ,"お支払日" ] ,format="%Y年%m月%d日"
)
h_mei[ ,"配当基準日"] <-
as.Date( h_mei[ ,"配当基準日" ],format="%Y年%m月%d日"
)
# 目検(目視にて検証)
> h_mei
銘柄名 銘柄コード お支払日 配当単価 数量 配当金額 所得税 地方税
1 SBIホールディングス (8473) 2020-06-08 80.0000000 600 48,000 7,351 0
2 以下余白 <NA> <NA> <NA> <NA> <NA> <NA> <NA>
端数処理代金 お受取金額 配当基準日
1 0 40,649 2020-03-31
2 <NA> <NA> <NA>
write.table( h_mei
,gsub( ".PDF" ,"_半角.txt" ,f ) )
"銘柄名" "銘柄コード" "お支払日" "配当単価" "数量" "配当金額" "所得税" "地方税" "端数処理代金" "お受取金額" "配当基準日"
"1" "SBIホールディングス" "(8473)" 2020-06-08 "80.0000000" "600" "48,000" "7,351" "0" "0" "40,649" 2020-03-31
"2" "以下余白" NA NA NA NA NA NA NA NA NA NA
感謝した記事
2017-10-12 Rで全角英数記号を半角にするのに{stringi}が役に立った話 https://pediatricsurgery.hatenadiary.jp/entry/2017/10/12/105242{stringr}/{stringi}とbaseの文字列処理について
https://rstudio-pubs-static.s3.amazonaws.com/92478_6704b96865e449b4bad7acb71443c8bc.html#文字列連結と分割str_cstr_split
#
大量データ
手元にある1年分のデータ(47ファイル)でテストしました。
前出のプログラムに手を入れて、こんな感じになりました。
##
ファイル単位
# ファイル名
f <- file.path(
FY # 会計年度(Fiscal Year)のディレクトリ
,"B_0988_SBI証券/配当" # 中間のディレクトリ
,"なんちゃら.PDF"
)
# PDF → CSV
mei <- 配当金( f )
# _全角csv
write.table( mei ,gsub( ".PDF" ,"_全角.txt" ,f ) )
# 半角 ← 全角
h_mei <- 半角( mei )
# _半角csv
write.table( h_mei ,gsub( ".PDF" ,"_半角.txt" ,f ) )
##
ディレクトリー単位
# PDF群のディレクトリー
d <- file.path( FY ,"B_0988_SBI証券/配当" )
files <- dir( d ,pattern = ".pdf$" ,ignore.case=T )
stack <- init()
for( a in 1:length( files ) ) {
f <- file.path( d ,files[ a ] ) # ファイル単位
mei <- 配当金( f )
stack <- rbind( stack ,mei )
}
# _全角csv
write.table( stack ,file.path( d ,"配当_全角.txt" ) )
# 全角 → 半角
h_mei <- 半角( stack )
# 照合
sum( as.integer( gsub( "," ,"" ,h_mei[ ,"配当金額"] ) ) ,na.rm=T )
sum( as.integer( gsub( "," ,"" ,h_mei[ ,"所得税"] ) ) ,na.rm=T )
sum( as.integer( gsub( "," ,"" ,h_mei[ ,"お受取金額"] ) ) ,na.rm=T )
# _半角csv
write.table( h_mei ,file.path( d ,"配当_半角.txt" ) )
##
まとめ
# pdfデータをインポートするため
library( pdftools )
# 全角→半角
library( stringi ) # install.packages("stringi")
# library( stringr ) # install.packages("stringr")
# 最終型
init <- function() {
# 列数と列名を初期化
配当金 <- data.frame( matrix( NA ,0 ,11 ) )
colnames( 配当金 ) <- c(
"銘柄名" ,"銘柄コード"
,"お支払日" ,"配当単価" ,"数量"
,"配当金額" ,"所得税" ,"地方税" ,"端数処理代金" ,"お受取金額"
,"配当基準日" )
return( 配当金 )
}
# y抽出
yn <- function( df ,p ,n ) {
# p:ページ
# n:明細行の"y"
x <- paste0( df[[ p ]]
[ df[[ p ] ]$"y" == n , ]$"x" )
x <- as.integer( x )
o <- order( c( x ) )
t <- paste0( df[[ p ] ]
[ df[[ p ] ]$"y" == n , ]$"text" )
return( t[ o ] )
}
# 日付の対処
ymd <- function( ve ) {
d <- grep( "日" ,ve )
if( length( d ) != 1 ) return( ve ) # ベクトルの要素が「1」である事
y <- grep( "年" ,ve )
switch( d
, "1" = {
if( y == 1 ) {
paste0( ve[ d ] ) # 年月日
} else
paste0( ve[ y ] ,ve[ d ] )
# (月日) (年) ※欧米かよ
}
, "2" = paste0( ve[1] ,ve[ d ])
# (年)月日 or (年月)日
, "3" = paste0( ve[1] ,ve[2] ,ve[ d ] )
# (年)(月)(日)
)
}
# 単価・数量の対処
unit <- function( ve ) {
u <- grep( "." ,ve )
if( length( u ) != 1 ) return() # ベクトルの要素が「1」である事
return( c( ve[u] ,ve[u+1] ) ) # "配当単価" 、"数量"
}
# 銘柄コードの対処
code <- function( ve ) {
n <- grep( ")" ,ve )
if( length( n ) != 1 ) return() # ベクトルの要素が「1」である事
switch( n
, "1" = paste0( ve[1] )
# "(NNNN)"
, "2" = paste0( ve[1] ,ve[2] )
# "(NNNN" ")" or "(" "NNNN)"
, "3" = paste0( ve[1] ,ve[2] ,ve[3] )
# "(" "NNNN" ")"
)
}
# 銘柄名の対処
name <- function( ve ) {
switch( length( ve )
, "1" = paste( ve[ 1 ] ) # "X"
, "2" = paste( ve[ 1 ] ,ve[ 2 ] ) # "X" and"YY"
)
}
# 上段
upper <- function( df ,p ) {
# p : ページ
y1 <- yn( df ,p ,91 )
y2 <- yn( df ,p ,100 )
y3 <- yn( df ,p ,94 )
y4 <- yn( df ,p ,126 )
y5 <- yn( df ,p ,139 )
y1 <- name( y1 ) # "X" と "YY" を結合
y2 <- code( y2 ) # "(nnnn" と ")" を結合
y3 <- c( ymd( y3 ) ,unit( y3 ) )
y5 <- ymd(y5)
return( c( y1 ,y2 ,y3 ,y4 ,y5 ) )
}
# 下段
lower <- function( df ,p ) {
# p : ページ
y6 <- yn( df ,p ,166 )
y7 <- yn( df ,p ,175 )
y8 <- yn( df ,p ,171 )
y9 <- yn( df ,p ,202 )
y10 <- yn( df ,p ,216 )
y6 <- name( y6 ) # "X" と "YY" を結合
y7 <- code( y7 )
y8 <- c( ymd( y8 ) ,unit( y8 ) )
y10 <- ymd(y10)
# 返り値
r <- c( y6 ,y7 ,y8 ,y9 ,y10 )
n <- length( r )
if ( n != 11 ) {
return( c( r ,rep( NA ,11-n ) ) )
} else { # 明細行であれば
return( r )
}
}
# 配当金
配当金 <- function( f ) {
# 入力
Pages <- pdf_info( f )$pages # 総ページ数
df <- pdf_data( f )
# 出力
mei <- init()
for( p in 1:Pages ) {
mei[ p * 2 -1 ,] <- upper( df ,p )
mei[ p * 2 ,] <- lower( df ,p )
}
return( mei )
}
# 半角
半角 <- function( mei ) {
han <- init()
# stri_trans_nfkc( mei ) #NG
for( i in 1:nrow( mei ) ) {
han[ i , ] <- stri_trans_nfkc( mei [ i , ] )
}
han[ ,"お支払日"] <- as.Date( han[ ,"お支払日" ] ,format="%Y年%m月%d日")
han[ ,"配当基準日"] <- as.Date( han[ ,"配当基準日" ] ,format="%Y年%m月%d日")
return( han )
}
以 上