Closed paithiov909 closed 2 years ago
こんにちは
調べ物をしていて発見したのですが、現在のzipanguの独自実装からstringi::stri_datetime_parseを使うように変えるとすごく速くなりそうです。また、「元年」や漢数字表記も、最近のICUだととくに変換しなくてもパースできるようです。
stringi::stri_datetime_parse
手もとで試してみているかぎりだと、現在の関数から置き換えてしまっても「文久3年」のテスト以外は通るかと思います(ICUだと明治より前の元号も変換できてしまうため。どうやら奈良時代以後の元号に対応しているらしい)。
この感じでも意図しない結果に変わってしまう値がなさそうなら、書き換えてしまうのもよさそうかなと思います。どうでしょうか?
require(magrittr) #> Loading required package: magrittr convert_jyear <- function(jyear) { jyear <- stringi::stri_trim(jyear) %>% stringi::stri_trans_nfkc() ifelse( stringi::stri_detect_regex(jyear, "[:number:]{3,}"), ## 和暦の年月日は実際上は3桁以上にならないと思われるため { ## 西暦と思われる場合 stringi::stri_datetime_parse( jyear, format = "yy\u5e74" ) %>% lubridate::year() }, { ## 和暦と思われる場合 jyear <- stringi::stri_trans_tolower(jyear) %>% stringi::stri_replace_all_regex( jyear_sets$pat_roman, jyear_sets$rep_roman, vectorise_all = FALSE ) %>% stringi::stri_replace_all_regex( jyear_sets$pat, jyear_sets$rep, vectorise_all = FALSE ) stringi::stri_datetime_parse( jyear, format = "Gy\u5e74", locale = "ja-JP-u-ca-japanese" ) %>% lubridate::year() } ) } convert_jdate <- function(date) { jdate <- stringi::stri_trim(date) %>% stringi::stri_trans_nfkc() jdate <- stringi::stri_trim(jdate) %>% stringi::stri_trans_tolower() %>% stringi::stri_replace_all_regex( jyear_sets$pat_roman, jyear_sets$rep_roman, vectorise_all = FALSE ) %>% stringi::stri_replace_all_regex( jyear_sets$pat, jyear_sets$rep, vectorise_all = FALSE ) ## 「Gy年M月d日」表記に揃える。現在は年月日ぜんぶないとエラーになるが、これだとエラーにはならない sp <- stringi::stri_split_regex( jdate, "(\u5e74|\u6708|\u65e5)|(\\.)|(\\-)|(\\/)", ) %>% purrr::map_chr(~ paste0(.[1], "\u5e74", .[2], "\u6708", .[3], "\u65e5")) stringi::stri_datetime_parse( sp, format = "Gy\u5e74M\u6708d\u65e5", locale = "ja-JP-u-ca-japanese" ) %>% lubridate::as_date() } jyear_sets <- list( pat_roman = c("meiji", "taisyo|taisho|taisyou", "syouwa|showa", "heisei", "rewiwa"), rep_roman = c("m", "t", "s", "h", "r"), pat = c("m|\u660e(?!\u6cbb)", "t|\u5927(?!\u6b63)", "s|\u662d(?!\u548c)", "h|\u5e73(?!\u6210)", "r|\u4ee4(?!\u548c)"), rep = c("\u660e\u6cbb", "\u5927\u6b63", "\u662d\u548c", "\u5e73\u6210", "\u4ee4\u548c") ) ### テスト ### years <- sample(c("令和2年", "平成5年", "明治元年", "1967年", NA), 100, replace = T) dates <- sample(c("令和元年5月21日", "昭和26年8月31日", "平成4年2月16日", NA), 100, replace = T) microbenchmark::microbenchmark( zipangu::convert_jyear(years), convert_jyear(years), times = 50L, check = "equivalent" ) #> Unit: milliseconds #> expr min lq mean median uq #> zipangu::convert_jyear(years) 58.1918 60.5191 68.157338 66.6875 73.3156 #> convert_jyear(years) 5.8456 6.1167 7.096138 6.4809 7.1068 #> max neval #> 88.9227 50 #> 19.7221 50 microbenchmark::microbenchmark( zipangu::convert_jdate(dates), convert_jdate(dates), times = 50L, check = "equivalent" ) #> Unit: milliseconds #> expr min lq mean median uq #> zipangu::convert_jdate(dates) 261.9986 279.6587 362.52175 314.4953 420.7269 #> convert_jdate(dates) 8.3647 8.8897 12.57395 9.8263 14.6133 #> max neval #> 816.9172 50 #> 45.1825 50
Created on 2022-05-17 by the reprex package (v2.0.1)
@paithiov909 ありがとうございます。stringi::stri_datetime_parse()の利用、勉強になります。 高速化についても有難いです。お手数でなければPRをいただけますでしょうか。
stringi::stri_datetime_parse()
わかりました。あとでPRを出してみます
こんにちは
調べ物をしていて発見したのですが、現在のzipanguの独自実装から
stringi::stri_datetime_parse
を使うように変えるとすごく速くなりそうです。また、「元年」や漢数字表記も、最近のICUだととくに変換しなくてもパースできるようです。手もとで試してみているかぎりだと、現在の関数から置き換えてしまっても「文久3年」のテスト以外は通るかと思います(ICUだと明治より前の元号も変換できてしまうため。どうやら奈良時代以後の元号に対応しているらしい)。
この感じでも意図しない結果に変わってしまう値がなさそうなら、書き換えてしまうのもよさそうかなと思います。どうでしょうか?
Created on 2022-05-17 by the reprex package (v2.0.1)