前提
以下のような約800万行4列の元データ(hyozyun)があります。
内訳は以下の通りです。
app_num: 番号
abii_name: 氏名
abii_addr: 住所
acai_app_dt: 日次
R
1head(hyozyun) 2 3app_num abii_name abii_addr acai_app_dt 42012000001 中山 明 埼玉県所沢市 20100101 52012000002 浦下 不比等 神奈川県横浜市 20100101 62012000003 高元 和人 東京都中野区 20100101 72012000004 岩澤 あや 高知県高知市 20100101 82012000009 手越 広一郎 東京都調布市 20100103 92012000009 手越 広明 東京都調布市 20100103 102012000010 市川 孝明 愛知県北名古屋市 20100104 112012000010 近藤 裕一 愛知県北名古屋市 20100104 122012000011 ウァング,ジョナサン エイ アメリカ合衆国 20100104
実現したいこと
以下のような、4列のロングデータ(名前:paneldata)を作成したいです。
pref_name: 都道府県、47種類
year:年、期間は2010/01-2021/12であるため、種類は12種類
month:月、期間は2010/01-2021/12であるため、種類は12種類
value:
元データ(hyozyun)について、以下の条件が該当する行数。
・abii_addr(住所)に、この行のpref_name(都道府県)が含まれている
・acai_app_dt(日次)に、この行のyear(年)及びmonth(月)が含まれている
イメージは以下のような感じです。
paneldata
pref_name | year | month | value |
---|---|---|---|
北海道 | 2010 | 1 | 25 |
北海道 | 2010 | 2 | 37 |
北海道 | 2010 | 3 | 45 |
... | |||
静岡県 | 2017 | 9 | 76 |
静岡県 | 2017 | 10 | 34 |
静岡県 | 2017 | 11 | 54 |
.... |
この場合ですと、行数は47都道府県×12年×12か月=6768行になります。
発生している問題、該当のソースコード
エラーは発生しておらず、動いてはいるのですが、元データ(hyozyun)が約800万行と膨大なのと、自分の知識不足により早く動くコードをかけず、何時間たっても処理が終わらない状態にあります。
遅延化している原因と改善案をご存じでしたら教えていただければ幸いです。
コードの流れは
1、データ読み込み
2、ロングデータ作成のための引数用のリストを作成
3、都道府県用リストを作成
4、表作成のための関数を作成
5、パネルデータ作成
となっています。
該当コードは以下の通りです。
コードが冗長なので、面倒な方はコード66行目の、#5 パネルデータ作成よりご覧ください。
なお、時間がかかっているのは、最後のパネルデータ作成の2重for構文です。それまでのコードは上手く迅速に処理できました。
R
1#1 データ読み込み 2 3hyozyun <- read_tsv("hyozyun.tsv", 4 locale = locale(encoding="UTF-8"), 5 show_col_types = FALSE 6 ) 7 8#2 抽出するデータの時期(年・月)のリストを作成(2010年1月-2021年12月) 9 10# 推計に使うデータの、始めと終わりの年月を指定 11SY = 2010 #開始年 12SM = 1 #開始月 13EY = 2021 #終了年 14EM = 12 #終了月 15 16T =((EY-SY+1)*12)-((SM-1)+(12-EM)) #使用するデータの総月数 17datelist_s = NULL #集計の引数用の、月始の年月日リスト準備 18datelist_e = NULL #集計の引数用の、月末の年月日リスト準備 19yearlist = NULL #パネルデータ用の、年リスト準備 20monthlist = NULL #パネルデータ用の、月リスト準備 21 22#集計用の月始月末の年月日リスト、パネルデータ用の年リスト、月リストを作成。 23for (i in 1:T) { 24 IY = SY + floor( (i - 1) / length(TM)) 25 IM = TM[(i-1) %% length(TM) +1] 26 IDATE_s = as.character(IY*10000 + IM*100 +1 ) 27 IDATE_e = as.character(IY*10000 + IM*100 +31 ) 28 datelist_s =c(datelist_s, IDATE_s) 29 datelist_e =c(datelist_e, IDATE_e) 30 yearlist =c(yearlist, IY) 31 monthlist =c(monthlist, IM) 32} 33 34datelist_s 35>"20100101","20100201","20100301",...,"20211201" 36datelist_e 37>"20100131","20100231","20100331",...,"20211231" 38yearlist 39>2010,2010,2010,2010,2010,2010,2010,2010,2010,2010,2010,2010,2011,2011,...,2021,2021 40monthlist 41>1,2,3,4,5,6,....,10,11,12 42length(datelist_s) 43>144 44length(datelist_s) 45>144 46length(yearlist) 47>144 48length(monthlist) 49>144 50 51#3 都道府県リスト作成 52 53pref_list <- c("北海道", "青森県","岩手県","宮城県","秋田県","山形県","福島県","茨城県","栃木県","群馬県","埼玉県","千葉県","東京都","神奈川県","新潟県","富山県","石川県","福井県","山梨県","長野県","岐阜県","静岡県","愛知県","三重県","滋賀県","京都府","大阪府","兵庫県","奈良県","和歌山県","鳥取県","島根県","岡山県","広島県","山口県","徳島県","香川県","愛媛県","高知県","福岡県","佐賀県","長崎県","熊本県","大分県","宮崎県","鹿児島県","沖縄県") 54 55pref_list2 <- paste0("^",pref_list) #都道府県名リスト、演算子付きリストを作成。 56P <- length(pref_list) #都道府県数 57 58#4 表を作るための関数を制作。 59createEmptyDf = function( nrow, ncol, colnames = c() ){ 60 if( missing( ncol ) && length( colnames ) > 0 ){ 61 ncol = length( colnames ) 62 } 63 data.frame( matrix( vector(), nrow, ncol, dimnames = list( c(), colnames ) ) ) 64} 65 66#5 パネルデータ作成 67 68#パネルデータ用の元の表を作成 69paneldata = createEmptyDf(P*T ,colnames = c("pref_name", "year", "month","patent")) 70 71 72#パネルデータを作成。 73for (pref in 1:P) {#上から都道府県ごとにデータを抽出 74 for (time in 1:T) {#各都道府県における各年月のデータを抽出 75 paneldata[(pref-1)*T+time, 1] = pref_list[pref] #1列目:都道府県 76 paneldata[(pref-1)*T+time, 2] = yearlist[time] #2列目:年 77 paneldata[(pref-1)*T+time, 3] = monthlist[time] #3列目:月 78 paneldata[(pref-1)*T+time, 4] = #4列目:合計数 79 .data = hyozyun %>% #元データを選択 80 filter(acai_app_dt >= datelist_s[time],acai_app_dt <= datelist_e[time]) %>% #同行の年月範囲のデータを抽出 81 filter(str_detect(abii_addr, pref_list2[pref])) %>% #同行の県に住所を置くデータを抽出 82 count() #抽出したの行数を合計 83 84 } 85}
上記のコード(というより最後の2重for構文)で膨大な時間がかかっているため、なるべく迅速なコードに変更したいです。ご存じの方がもしいらっしゃいましたら教えていただければ幸いです。
試したこと
素人ながら調べたところ、Rとforの相性が悪い、何度もfor構文の中で同じ呼び出しをしているなどを行っていると遅くなりやすいとありましたが、こちらの上手い変更方法が思いつきません。
またhyozyunデータを数万行削減したりしましたが、あまり効果はありませんでしたので、この構文を迅速化しなければならないようです。

回答1件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。