読者です 読者をやめる 読者になる 読者になる

Advanced Rを読んで知ったこと(1) Replacement functions

R Advanced R

さいきん、ggplot2とかplyrで有名なHadleyさんが書いたこれ↓読んでるわけですが、、

Welcome · Advanced R.

内容濃すぎる!!
アートオブRプログラミング を買うよりもこっち読んだ方がいいんじゃないか。

ちょこちょこ読むので、ちょこちょこ気づいたことをメモしておこうと思います。

今回知らなかったなーと思ったのは、

Functionsに書いてあったReplacement functionsのこと。

たとえば、オブジェクトが持っている要素名をリストアップするnamesという関数があります。
具体的には、こんな感じです。

> a <- list(cat=1, dog=4)
> a
$cat
[1] 1

$dog
[1] 4

> names(a)
[1] "cat" "dog"

じゃあ要素名を変えたいときはどうすればいいかというと、
このnamesに値を束縛する的な(表現あってるか自信がないです。。)ことをすればよくて、
こんな具合になります。

> names(a) <- c("猫","犬")
> a
$猫
[1] 1

$犬
[1] 4

なんでこんなことできるんだろう、と内心ずっと不思議に思ってたんですが、
namesに対応するnames<-という関数があるらしいです。

> `names`
function (x)  .Primitive("names")
> `names<-`
function (x, value)  .Primitive("names<-")

このxxxx<-という形の関数が「replacement functions」で、
値を置き換えてくれるように見えるらしいです。

ように見える、というのはどういうことかというと、
内部的にはコピーを作ってるだけ、らしい。

I say they "act" like they modify their arguments in place, because they actually create a modified copy. We can see that by using pryr::address() to find the memory address of the underlying object.

と書いてあったのでやってみた。

> library(devtools)
> install_github("pryr")
...
> a <- list(cat=1, dog=4)
> address(a)
[1] "0x2508a5f8"
> names(a) <- c("猫","犬")
> address(a)
[1] "0x2508a940"

なるほど。
R、奥が深いというか闇が深いというか。。

まあとりあえず読み切れるようにがんばろう。