質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.47%
RStudio

RStudioは、Rのプログラミングを効率化する統合開発環境です。統計計算とグラフィックスができるプログラミング言語であるRのIDEでOSSで公開されています。ソースコードやコンソールなどが一つの画面に見やすく配置されている点が特徴。コマンド名以外に、関数名やパッケージ名も補完できます。

R

R言語は、「S言語」をオープンソースとして実装なおした、統計解析向けのプログラミング言語です。 計算がとても速くグラフィックも充実しているため、数値計算に向いています。 文法的には、統計解析部分はS言語を参考にしており、データ処理部分はSchemeの影響を受けています。 世界中の専門家が開発に関わり、日々新しい手法やアルゴリズムが追加されています。

Windows

Windowsは、マイクロソフト社が開発したオペレーティングシステムです。当初は、MS-DOSに変わるOSとして開発されました。 GUIを採用し、主にインテル系のCPUを搭載したコンピューターで動作します。Windows系OSのシェアは、90%を超えるといわれています。 パソコン用以外に、POSシステムやスマートフォンなどの携帯端末用、サーバ用のOSもあります。

Q&A

解決済

3回答

278閲覧

R言語における、mutate()及びif_else()構文の効率化

maltines

総合スコア12

RStudio

RStudioは、Rのプログラミングを効率化する統合開発環境です。統計計算とグラフィックスができるプログラミング言語であるRのIDEでOSSで公開されています。ソースコードやコンソールなどが一つの画面に見やすく配置されている点が特徴。コマンド名以外に、関数名やパッケージ名も補完できます。

R

R言語は、「S言語」をオープンソースとして実装なおした、統計解析向けのプログラミング言語です。 計算がとても速くグラフィックも充実しているため、数値計算に向いています。 文法的には、統計解析部分はS言語を参考にしており、データ処理部分はSchemeの影響を受けています。 世界中の専門家が開発に関わり、日々新しい手法やアルゴリズムが追加されています。

Windows

Windowsは、マイクロソフト社が開発したオペレーティングシステムです。当初は、MS-DOSに変わるOSとして開発されました。 GUIを採用し、主にインテル系のCPUを搭載したコンピューターで動作します。Windows系OSのシェアは、90%を超えるといわれています。 パソコン用以外に、POSシステムやスマートフォンなどの携帯端末用、サーバ用のOSもあります。

1グッド

0クリップ

投稿2023/12/05 13:59

実現したいこと

以下のことをそれぞれ実行するコードを書いたのだが、実行の完了に非常に時間がかかっている。
元データが膨大なせいか、書いているコードに問題があるのか分からない。
効率的なコードを書きたい。

  • 年月日の変数から、年、月、日をそれぞれ抜き出す。
  • ID()の変数から、IDを構成する部分を分離する。
  • 住所の変数が空白の場合、県コードの変数に"00"を代入する。

前提

データセットの変数は以下の通り。なお、1543万行ある膨大なデータ。

ida : 1つ目のID。10桁の数字。数値。(例:2011473923)
seq : 2つ目のID。1-3桁の数字。数値(例:2)
ida_seq : idaとseqを"_"で接続した変数。文字列。seqは3桁になっている。(例:"2011473923_002")
date :年月日。文字列。yyyy-mm-dd方式。(例:"2011-06-18")
year : 年。数値。(例:2011)
month : 月。数値。(例:6)
day : 日。数値。(例:18)
address : 住所が文字列で入っている。(例:東京都千代田区1丁目1-1)
pref_code : 住所に対応した県コードが2桁の文字列で入っている。(例:"13")

発生している問題

以下のコードを実行しているのだが、実行に時間が非常にかかっている。
遅くなっている原因と、効率化する解決策をもしご存じであれば教えていただきたい。

該当のソースコード

data <- data %>% mutate(year = as.numeric(substr(date,1,4)), month = as.numeric(substr(date,6,7)), day = as.numeric(substr(date,9,10)), ida = as.numeric(substr(ida_seq,1,10)), seq = as.numeric(substr(ida_seq,12,14)), pref_code = if_else(is.na(address),"00",pref_code) )

試したこと

year,day,monthをそれぞれ関数(year())で実行したものの、あまり効率化にはならなかった。
if_else()がdpfyrと相性が悪いと推測して、デフォルトのifelse()にもしてみたが、あまり変わらなかった。

補足情報(FW/ツールのバージョンなど)

使用しているのはRStudio。最新版ではないが3か月前にダウンロードしたもの。

KojiDoiを押しています

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

melian

2023/12/05 14:59

その「1543万行ある膨大なデータ」の元は CSV ファイルでしょうか? そうでしたら、R ではなく別の方法で CSV ファイルを加工する方がよいのではないかと思います。(例えばマルチコア環境 + GNU parallel + awk で分割並列処理など)
maltines

2023/12/05 15:29

ご助言ありがとうございます。 元のデータはTSVデータです。 環境変化以外には高速化は望めないということでしょうか?
melian

2023/12/05 15:52

multidplyr という並列処理のパッケージがあるのですが、書き方によってはコンテキスト・スイッチなどのオーバーヘッドが大きくなってしまい、結果的に遅くなってしまう場合がある様です。他には date でグループ化すれば同一の年月日の場合は1回の分割で済むでしょう。
guest

回答3

0

自己解決

mutate()を使わずベクトル処理を行うと一瞬で終わりました。

原因はわからないですが、問題は解決しました。多くのご助言いただき誠にありがとうございました。

投稿2023/12/15 23:43

maltines

総合スコア12

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

year,day,monthをそれぞれ関数(year())で実行したものの、あまり効率化にはならなかった。

あくまで私の環境「macOS(M1) 13.6.1, R 4.3.2, tidyverse 2.0.0」が前提ですが,1543万行の類似データ(TSV 形式)を作成し計測したところ,関数 year() month() day() を使用することで一応の時間短縮(オリジナル:約41秒,変更後:約20秒)はできているようです。御参考になれば幸いです。

下記に記述例と出力結果を示します。

R

1library(tidyverse) 2 3data <- read_tsv("sample.tsv", show_col_types=FALSE) 4 5start <- Sys.time() 6data <- data |> 7 ## mutate(year = as.numeric(substr(date,1,4)), 8 ## month = as.numeric(substr(date,6,7)), 9 ## day = as.numeric(substr(date,9,10)), 10 ## ida = as.numeric(substr(ida_seq,1,10)), 11 ## seq = as.numeric(substr(ida_seq,12,14)), 12 ## pref_code = if_else(is.na(address),"00",pref_code)) 13 mutate(year = year(date), 14 month = month(date), 15 day = day(date), 16 ida = as.numeric(substr(ida_seq, 1, 10)), 17 seq = as.numeric(substr(ida_seq, 12, 14)), 18 pref_code = if_else(is.na(address), "00", pref_code)) 19end <- Sys.time() 20print(end - start) 21 22print(data)
Time difference of 19.70094 secs # A tibble: 15,430,000 × 9 ida_seq date pref_code address year month <chr> <date> <chr> <chr> <dbl> <dbl> 1 2010000000_000 2010-09-07 13 東京都千代田区1-1-1 2010 9 2 2010000001_001 2010-02-03 14 神奈川県横浜市中区日本大通1 2010 2 3 2010000002_002 2010-07-03 09 栃木県宇都宮市塙田1-1-20 2010 7 4 2010000003_003 2010-05-24 08 茨城県水戸市笠原町978-6 2010 5 5 2010000004_004 2010-04-23 10 群馬県前橋市大手町1-1-1 2010 4 6 2010000005_005 2010-02-06 00 NA 2010 2 day ida seq <int> <dbl> <dbl> 1 7 2010000000 0 2 3 2010000001 1 3 3 2010000002 2 4 24 2010000003 3 5 23 2010000004 4 6 6 2010000005 5 # ℹ 15,429,994 more rows

投稿2023/12/07 11:14

little_street

総合スコア319

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

Rの文字列処理は遅いので、これが足を引っ張っているかもしれません。私なら、前処理にperlを使います。元データからdateだのseqだの抜き出す処理してそれを別ファイルに書き出すのです。

$ cat test231207.tsv 2011-06-18 20114473923_002 東京都千代田区1丁目1-1 13 2011-06-18 20114473923_002 東京都千代田区1丁目1-1 perl -F"\t" -CSDA -Mutf8 -alnE '($y,$m,$d)=$F[0]=~/(\d+)-(\d+)-(\d+)/; ($ida,$seq)=$F[1]=~/(\d+)_(\d+)/; print join("\t", $y,$m,$d,$ida,$seq,$F[2],($F[3]||"00"))' test231207.tsv 2011 06 18 20114473923 002 東京都千代田区1丁目1-1 13 2011 06 18 20114473923 002 東京都千代田区1丁目1-1 00

投稿2023/12/07 05:17

KojiDoi

総合スコア13671

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.47%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問