これのもうちょっと回りくどい版の記事を書きます。
ls()
ls()
は、指定した環境中にあるオブジェクト名の一覧を取得する関数です。
引数に何も指定しなければ、その関数を実行した環境を調べます。 つまり、コンソールで実行した場合は、ユーザがいろんな変数を定義したりする「グローバル環境」を調べます。 グローバル環境には、はじめは何もありません。
ls() #> character(0)
ここで、x
という変数を定義すると、たしかにx
が増えるのがわかります。
x <- 1 ls() #> [1] "x"
どの環境をls()
したいか指定することもできます。
Rにはグローバル環境を指す.GlobalEnv
という変数があらかじめ定義されているのでそれを指定してみましょう。
ls(.GlobalEnv) #> [1] "x"
上と同じ結果が得られました。
ここでは環境そのものを引数に渡しましたが、実はls()
に環境を指定する方法は他にもあります。
以下のように文字列を指定しても同じようにグローバル環境を調べてくれます。また、数字を指定することもできます。
ls(".GlobalEnv") #> [1] "x" ls(1) #> [1] "x"
これはどういう仕組みなのでしょう。?ls
によると、
The name argument can specify the environment from which object names are taken in one of several forms: as an integer (the position in the search list); as the character string name of an element in the search list; or as an explicit environment
と書かれています。「search list」というのは、オブジェクトを探すときに探索される環境のリストで、search()
で見ることができるものです。
文字列を指定したときにはこの中で一致する名前の環境、数字を指定したときはこの並びの中で指定した順番の環境が使われます。
search() #> [1] ".GlobalEnv" "tools:rstudio" "package:stats" "package:graphics" "package:grDevices" #> [6] "package:utils" "package:datasets" "package:methods" "Autoloads" "package:base"
まとめると、ls()
への環境の指定の仕方は
- 環境そのものを渡す
- 環境の名前を文字列で渡す
- 環境の位置を数字で渡す
の3つがあります。これらそれぞれにenvir
、name
、pos
という引数を使い分けないといけない時代がかつてあったようですが、
今は「Mostly there for back compatibility.」と書かれているので、引数の名前は指定せず適当にls()
に渡してしまって大丈夫みたいです。
環境
さて、「オブジェクトを探すときに探索される環境」と書きましたが、これはどういうことなのでしょう。
たとえば、先ほどはx
を定義しました。コンソールにx
と打った時、Rはまず.GlobalEnv
の中を探索します。そこで同じ名前のものが見つかるのでそれを使います。
x
#> [1] 1
しかし、たとえばhead
というオブジェクトはグローバル環境にはありません。
なければ、「search list」の1つ上、つまりtools:rstudio
を探します。
なければ次に、pacckage:stats
を探します。
...という具合の探索を繰り返し、ls
はpackage:utils
で見つかります。
"head" %in% ls("package:utils") #> [1] TRUE
という感じの話は、パンダ本の8章とか9章あたりに書いてあった気がするので買って読みましょう(ステマ)。
Rプログラミング本格入門: 達人データサイエンティストへの道
- 作者: Kun Ren,湯谷啓明,松村杏子,市川太祐,ホクソエム
- 出版社/メーカー: 共立出版
- 発売日: 2017/11/23
- メディア: 単行本
- この商品を含むブログ (1件) を見る
さて、このpackage:utils
というのはutilsパッケージの環境です。しかし、utilsパッケージで定義されている*1オブジェクトすべてがここに含まれているわけではありません。
みなさんご存知のように、パッケージにはlibrary()
でパッケージを読み込めば使えるようになる関数と、:::
で呼び出さないと使えない関数とがあります。
package:utils
というのはutilsパッケージのオブジェクトのうち、前者、つまりエクスポートされているもののみを集めた名前空間なのです。
後者は、パッケージ内のオブジェクトすべてを含んでいます。この環境を取得する方法はいろいろありますが、たとえば、environment()
という関数で、ある関数やフォーミュラがどの環境にあるか調べることができます。
これをhead
に使ってみましょう。
environment(head) #> <environment: namespace:utils>
namespace:utils
というのが出てきました。これは、utils
パッケージ内で定義されているすべてのオブジェクトを含んでいます。
ls()
した結果を比べてみると分かると思います。
length(ls(environment(head))) #> [1] 492 length(ls("package:utils")) #> [1] 241
まとめ
みたいな感じの事をぐだぐだ説明するにはr-wakalangの余白が狭すぎるなあ、とか思ったりします。 どうするのがいいんですかね...。とりあえず引き続き質問・意見お待ちしています。
次回Tokyo.Rは、Rのことならなんでも質問できる場所「r-wakalang」での質問の仕方を話そうと思っています。r-wakalangで質問するときどんな壁がありますか? 期間限定でhttps://t.co/GgUtj559KYに復活するのでご意見・質問をお寄せください!🙏(このツイートへのリプでも👌) https://t.co/oEo3Cjh94E
— Hiroaki Yutani (@yutannihilation) 2018年2月21日
タグでつぶやきたい場合は #ここがわからんRワカラング とかで。
— Hiroaki Yutani (@yutannihilation) 2018年2月21日
*1:「定義されている」という表現はたぶん正確じゃないですが、まあ説明のためということで...