簡単な背景:広く使われている多くの(ほとんど?)現代のプログラミング言語には、少なくとも少数のADT [抽象データ型]が共通してあり、特に、
文字列(文字で構成されるシーケンス)
リスト(値の順序付けられたコレクション)、および
マップベースのタイプ(キーを値にマップする順序付けされていない配列)
Rプログラミング言語では、最初の2つはそれぞれcharacter
ととして実装されvector
ます。
私がRを学び始めたとき、2つのことはほぼ最初から明らかでした:list
Rで最も重要なデータ型(これはRの親クラスであるためdata.frame
)、そして次に、少なくともそれらがどのように機能するか理解できませんでした私のコードでそれらを正しく使用するには十分ではありません。
1つには、Rのlist
データ型はマップADT(dictionary
Python、NSMutableDictionary
Objective C、hash
PerlおよびRuby、object literal
Javascriptなど)の単純な実装であるように思えました。
たとえば、Pythonの辞書と同じように、キーと値のペアをコンストラクタに渡すことで作成します(Pythonではこれはdict
できませんlist
)。
x = list("ev1"=10, "ev2"=15, "rv"="Group 1")
そして、R辞書の項目には、Python辞書の項目と同じようにアクセスしますx['ev1']
。同様に、「キー」または「値」のみを取得できます。
names(x) # fetch just the 'keys' of an R list
# [1] "ev1" "ev2" "rv"
unlist(x) # fetch just the 'values' of an R list
# ev1 ev2 rv
# "10" "15" "Group 1"
x = list("a"=6, "b"=9, "c"=3)
sum(unlist(x))
# [1] 18
しかし、Rのlist
Sもあるとは違って(私はとにかく学んだ言語の中から)他のマップ型のADT。私の推測では、これはSの初期仕様、つまりデータ/統計DSL [ドメイン固有の言語]をゼロから設計する意図の結果です。
list
広く使用されている他の言語(Python、Perl、JavaScriptなど)におけるR とマッピングタイプの3つの重要な違い:
まず、list
Rのsは、値がキー付きであっても、ベクトルと同様に順序付けられたコレクションです(つまり、キーは、連続した整数だけでなく、ハッシュ可能な任意の値にすることができます)。ほとんどの場合、他の言語のマッピングデータタイプは順序付けされていません。
2つ目は、関数を呼び出しlist
たlist
ときにaを渡したことがなく、またを返した関数に(明示的な)コンストラクターが含まれていなくても、関数からsを返すことができます(もちろん、これを実際に処理するには返された結果を)の呼び出しでラップします。list
list
unlist
x = strsplit(LETTERS[1:10], "") # passing in an object of type 'character'
class(x) # returns 'list', not a vector of length 2
# [1] list
第三 Rさんの独特の機能list
S:彼らが別のADTのメンバーであることを思われない、とあなたがそれを行うにしようとした場合、その後一次容器はに強制されますlist
。例えば、
x = c(0.5, 0.8, 0.23, list(0.5, 0.2, 0.9), recursive=TRUE)
class(x)
# [1] list
ここでの私の意図は、言語やそれがどのように文書化されているかを批判することではありません。同様に、list
データ構造やその動作に問題があることを示唆しているわけではありません。私が修正したいのは、コードで正しく使用できるように、それらがどのように機能するかについての私の理解です。
以下は、私がよりよく理解したいことです。
関数呼び出しがいつ返されるかを決定するルールは何ですか
list
(たとえば、strsplit
上記の式)。に名前を明示的に割り当てない場合
list
(例:)list(10,20,30,40)
は、デフォルトの名前は1で始まる連続した整数だけですか?(私は仮定しますが、答えがイエスであると確信しているわけではありません。そうでない場合、このタイプをlist
への呼び出しを含むベクトルに強制することはできませんunlist
。)なぜ、これらの二つの異なるオペレータは、ん
[]
、と[[]]
、返す同じ結果を?x = list(1, 2, 3, 4)
どちらの式も「1」を返します。
x[1]
x[[1]]
これらの2つの式が同じ結果を返さないのはなぜですか?
x = list(1, 2, 3, 4)
x2 = list(1:4)
Rのドキュメント(?list
、R-intro
)を私に向けないでください-私はそれを注意深く読みましたが、上で述べた種類の質問に答えるのに役立ちません。
(最後に、私は最近知り、S4クラスを介して従来のマップタイプの動作hash
を実装するRパッケージ(CRANで利用可能)と呼ばれるRパッケージの使用を開始しました。このパッケージをお勧めします。)
list
、Rがハッシュのようではない方法のリストを広げていることに気づきませんでした。もう1つ、注目に値すると思います。 list
Rでは、同じ参照名を持つ2つのメンバーを持つことができます。それobj <- c(list(a=1),list(a=2))
が有効であり、2つの名前付き値「a」を含むリストを返すと考えてください。このインスタンスでは、の呼び出しobj["a"]
は最初に一致したリスト要素のみを返します。Rの環境を使用して、参照された名前ごとに1項目のみのハッシュに類似した(おそらく同一の)動作を得ることができます。例x <- new.env(); x[["a"]] <- 1; x[["a"]] <- 2; x[["a"]]
x = list(1, 2, 3, 4)
、これらの両方が同じ結果を返しませんx[1]
、とx[[1]]
。1つ目はリストを返し、2つ目は数値ベクトルを返します。下にスクロールすると、この質問に正しく回答した回答者はダークだけだったようです。