Hatena::ブログ(Diary)

盆栽日記

2016-08-19

paste0関数の挙動

こんな話がある。

結論からいえば、三連ドット(...)で引数を受ける+引数のチェックを明示的に行わなかった結果だと思われる。

原因を探る

paste0関数内部をみると.InternalでC実装のpaste0が呼ばれている。

> paste0
function (..., collapse = NULL) 
.Internal(paste0(list(...), collapse))
<bytecode: 0x000000000581fef0>
<environment: namespace:base>

.Internalの中身を見るにはソースを見たらよい。

https://github.com/wch/r-source

names.cを確認すると、C実装のpasteと同様にdo_pasteが呼ばれている。

pasteとの違いはpaste0の場合、offsetが1(pasteは0)でarityが2(pasteは3)という点である。

https://github.com/wch/r-source/blob/48536f1756a88830076023db9566fbb2c1dbb29b/src/main/names.c#L514

offsetは動作を切り替えるフラグであり次のdo_pasteの中ではopとして扱われている。

arityは引数の数を示しており(paste0はlist(...)とcollapseの2つ、pasteはsepが加わって3つ)。

さて、今度は呼ばれるdo_pasteの中身をみてみる。

https://github.com/wch/r-source/blob/trunk/src/main/paste.c#L52

ここではoffset(op)をチェックして0ならばuse_sepがTRUEになる。

つまりpaste0ならuse_sepはFALSEである。

use_sepがTRUEの時はsep引数の値をみて処理を行っているが、

FALSEの時はsep引数にnilを入れるのみでありチェックは行われない。

https://github.com/wch/r-source/blob/trunk/src/main/paste.c#L77

結果として、sepに限らずどんな引数でも渡せるようになっており

冒頭の例の他にも以下のような例でも通る。

> paste0(1,2,yeah=1)
[1] "121"
> paste0(1,2,takayanagi=3)
[1] "123"

三連ドット(...)で引数を受ける+引数のチェックを明示的に行わなかった結果、以上のような挙動になっているものと思われる。

三連ドットは便利だけど、Advanced RのFunctionsの章にもあるように、引数のチェックが行われず思わぬ挙動を示す((

sep引数なんてそもそもこの関数の引数として用意してないんだから使うなよといえばそれまでだが))。

paste0関数はその良い例とも言える。

2016-08-15

10進数を2進数に変換する

なるべく組み込み関数で処理したい。intToBits関数を使うのが良さそう。

以下は16桁の2進数で表現している。

> paste(rev(as.integer(intToBits(10739))[1:16]), collapse="")
[1] "0010100111110011"

2016-08-08

メモリに乗らないデータを分割して読み込んでくれるパッケージ

最近readrパッケージが1.0になった。

https://blog.rstudio.org/2016/08/05/readr-1-0-0/

この中で「実験的だが」という断りつきでread_csv_chunked関数が最後に紹介されている。

メモリに乗らないようなデータを分割して読み込むことができる。

baseのread.**関数群も読み込み行数および読み込み開始位置は指定できたので、今までできなかったというわけではないが、1回の読み込みデータ数を指定すればあとはfor文を書かずともよしなにやってくれるので楽ではある。

しかも毎回の読み込み時に呼び出されるコールバック関数も指定できる。

以下は毎回20ずつデータを読み込み、そのたびにstr関数を呼ぶ例。

library("readr")
read_csv_chunked(file=readr_example("mtcars.csv"), callback=str, chunk_size = 20)

chunkedパッケージの方が便利かも

そういえばこういうコンセプトのパッケージ、UseR!2016で話題になっておりRワカラングでも盛り上がっていた憶えがある。

盛り上がっていたことしか覚えていなくて難儀したが、chunkedパッケージというのがそれ。

(レポジトリ)

https://github.com/edwindj/chunked

(UseRの発表資料)

https://github.com/edwindj/chunked/blob/master/useR2016/lightning.pdf

LaFパッケージを内部的に利用しつつ、dplyrの思想に合うように作られている。

以下は公式のヘルプを転載したもの。

library("chunked")
  read_chunkwise("./large_file_in.csv", chunk_size=5000) %>% 
  select(col1, col2, col5) %>%
  filter(col1 > 10) %>% 
  mutate(col6 = col1 + col2) %>% 
  write_chunkwise("./large_file_out.csv")

最近忘れっぽい&Rワカラングだとすぐ流れてしまう、のでメモしておく。

誰か解説書いてください。

2016-06-22

Jupyter notebook のnbextensionsを入れようとしたらうまくいかなかったのでAnaconda Extensionsを入れた話

Anaconda経由で入れたjupyter notebookのnbextensionを使いたい。

特に、見出しをtocでまとめてくれる"Table of Contents (2)"を使いたい。

しかし以下のようなメッセージが出て、http://localhost:8888/nbextensions/ にアクセスできない。

"Config option 'nbserver_extensions' not recognized by 'NotebookApp' "

色々調べていたらAnaconda Extensionsを使えばいいということがわかった。

https://github.com/Anaconda-Platform/anaconda-nb-extensions

以下のコマンドでインストールできる。

conda install anaconda-nb-extensions -c anaconda-nb-extensions

あとはhttp://localhost:8888/nbextensions/ にアクセスすればよい。

2016-06-13

cell magicとline magic

Jupyter notebookというかIPythonのrmagicを使ってて、%Rと%%Rの違いがわからなかったので調べた。

%という表記の問題でやたらググりにくいのでメモしておく。

結論から言うと、%1つだとline magic、%%2つだとcell magicである。

magic function

IPythonにはmagic functionと呼ばれるものがある。

IPython組み込みのものだと以下にリストアップされている。

http://ipython.readthedocs.io/en/stable/interactive/magics.html

この中で%1つから始まるコマンドがline magic、%%2つから始まるコマンドがcell magicである。

line magic、cell magicはそれぞれmagic functionの適用範囲で分かれている。

line magicは同一行のコマンドのみに適用され、cell magicは同一セルのコマンドに適用される。

詳しいことは以下のチュートリアルに書いてあるので適宜参照のこと。

http://ipython.readthedocs.io/en/stable/interactive/tutorial.html#magic-functions

お元気で。