回答:
R言語定義は、次のタイプの質問に答えるのに便利です。
Rには3つの基本的なインデックス演算子があり、構文は次の例で表示されます。
x[i] x[i, j] x[[i]] x[[i, j]] x$a x$"a"
ベクトルと行列の場合、
[[
フォームとの意味上の違いが少しありますが、フォームが使用されることはほとんどありません[
(たとえば、名前やdimnames属性が削除され、文字インデックスに部分一致が使用されます)。単一のインデックスで多次元構造にインデックスを付ける場合、x[[i]]
またはx[i]
のi
th番目の順次要素を返しx
ます。リストの場合、通常は
[[
任意の単一の要素を選択するために使用します[
が、選択した要素のリストを返します。この
[[
形式では、整数または文字インデックスを使用して単一の要素のみを選択[
できますが、ベクトルによるインデックス付けは可能です。ただし、リストの場合、インデックスはベクトルにすることができ、ベクトルの各要素はリスト、選択されたコンポーネント、そのコンポーネントの選択されたコンポーネントなどに順に適用されます。結果はまだ単一の要素です。
[
あなたが同じ出力クラスを取得し、リスト手段返す常にx[v]
かかわらずの長さのをv
。たとえばlapply
、リストのサブセットを上書きしたい場合がありますlapply(x[v], fun)
。[
長さ1のベクトルのリストをドロップすると、長さが1の場合は常にエラーが返されますv
。
2つのメソッドの大きな違いは、抽出に使用したときに返されるオブジェクトのクラスと、それらが値の範囲を受け入れるか、割り当て時に単一の値のみを受け入れるかです。
次のリストのデータ抽出の場合を検討してください。
foo <- list( str='R', vec=c(1,2,3), bool=TRUE )
fooからboolに格納された値を抽出して、if()
ステートメント内で使用したいとします。これは、の戻り値[]
と[[]]
、それらがデータ抽出に使用される場合の違いを示しています。この[]
メソッドは、クラスリストのオブジェクト(またはfooがdata.frameの場合はdata.frame)を返します。[[]]
オブジェクトを返しますがメソッドは、値の型によってクラスが決定されるオブジェクトを返します。
したがって、この[]
メソッドを使用すると、次のようになります。
if( foo[ 'bool' ] ){ print("Hi!") }
Error in if (foo["bool"]) { : argument is not interpretable as logical
class( foo[ 'bool' ] )
[1] "list"
これは、[]
メソッドがリストを返し、リストがif()
ステートメントに直接渡す有効なオブジェクトではないためです。この場合[[]]
、適切なクラスを持つ「bool」に格納された「ベア」オブジェクトを返すため、これを使用する必要があります。
if( foo[[ 'bool' ]] ){ print("Hi!") }
[1] "Hi!"
class( foo[[ 'bool' ]] )
[1] "logical"
2つ目の違いは、オペレーターは単一のスロットまたは列へのアクセスに制限されているのに対し、オペレーターはリスト内のスロットまたはデータフレーム内の列に[]
アクセスするために使用できることです。2番目のリストを使用して値を割り当てる場合を考えます。[[]]
bar()
bar <- list( mat=matrix(0,nrow=2,ncol=2), rand=rnorm(1) )
fooの最後の2つのスロットをbarに含まれるデータで上書きしたいとします。[[]]
演算子を使用しようとすると、次のようになります。
foo[[ 2:3 ]] <- bar
Error in foo[[2:3]] <- bar :
more elements supplied than there are to replace
これは、[[]]
が単一の要素へのアクセスに限定されているためです。私たちは使用する必要があります[]
:
foo[ 2:3 ] <- bar
print( foo )
$str
[1] "R"
$vec
[,1] [,2]
[1,] 0 0
[2,] 0 0
$bool
[1] -0.6291121
割り当てが成功した間、fooのスロットは元の名前を保持したことに注意してください。
二重ブラケットはリスト要素にアクセスしますが、単一ブラケットは単一要素のリストを返します。
lst <- list('one','two','three')
a <- lst[1]
class(a)
## returns "list"
a <- lst[[1]]
class(a)
## returns "character"
[]
リストを[[]]
抽出し、リスト内の要素を抽出します
alist <- list(c("a", "b", "c"), c(1,2,3,4), c(8e6, 5.2e9, -9.3e7))
str(alist[[1]])
chr [1:3] "a" "b" "c"
str(alist[1])
List of 1
$ : chr [1:3] "a" "b" "c"
str(alist[[1]][1])
chr "a"
ここに追加するだけで[[
、再帰的なインデックス作成にも対応しています。
これは、@ JijoMatthewの回答でほのめかされましたが、調査されませんでした。
で説明したように?"[["
、のような構文はx[[y]]
、length(y) > 1
として解釈されます。
x[[ y[1] ]][[ y[2] ]][[ y[3] ]] ... [[ y[length(y)] ]]
注これは、しないの違いについてあなたの主なテイクアウトどうあるべきかを変更する[
と[[
-前者はのために使用されていること、すなわちサブセット化、そして後者はのために使用されている抽出単一のリスト要素を。
例えば、
x <- list(list(list(1), 2), list(list(list(3), 4), 5), 6)
x
# [[1]]
# [[1]][[1]]
# [[1]][[1]][[1]]
# [1] 1
#
# [[1]][[2]]
# [1] 2
#
# [[2]]
# [[2]][[1]]
# [[2]][[1]][[1]]
# [[2]][[1]][[1]][[1]]
# [1] 3
#
# [[2]][[1]][[2]]
# [1] 4
#
# [[2]][[2]]
# [1] 5
#
# [[3]]
# [1] 6
値3を取得するには、次のようにします。
x[[c(2, 1, 1, 1)]]
# [1] 3
上記の@JijoMatthewの答えに戻って、思い出してr
ください:
r <- list(1:10, foo=1, far=2)
特に、これは、を誤用したときに発生する傾向のあるエラー[[
、つまり次のことを説明しています。
r[[1:3]]
エラー
r[[1:3]]
:レベル2で再帰的なインデックス作成が失敗しました
このコードは実際にを評価しようとしたためr[[1]][[2]][[3]]
、r
レベル1 で停止がネストされているため、再帰的なインデックス作成による抽出の試行は、[[2]]
は、レベル2で。
エラー
r[[c("foo", "far")]]
:下付き文字が範囲外です
ここで、Rは探していました r[["foo"]][["far"]]
存在しないを、添え字が範囲外のエラーになります。
これらのエラーの両方が同じメッセージを出力した場合、おそらくもう少し役立つ/一貫性があるでしょう。
どちらもサブセット化の方法です。単一のブラケットは、リストのサブセットを返します。それ自体がリストになります。つまり、複数の要素が含まれる場合と含まれない場合があります。一方、二重括弧はリストから単一の要素のみを返します。
-単一ブラケットは私達にリストを与えます。リストから複数の要素を返したい場合は、単一のブラケットを使用することもできます。次のリストを検討してください:
>r<-list(c(1:10),foo=1,far=2);
リストを表示しようとすると、リストが返される方法に注意してください。rと入力してEnterキーを押します
>r
#the result is:-
[[1]]
[1] 1 2 3 4 5 6 7 8 9 10
$foo
[1] 1
$far
[1] 2
今、私たちは単一のブラケットの魔法を見ます:-
>r[c(1,2,3)]
#the above command will return a list with all three elements of the actual list r as below
[[1]]
[1] 1 2 3 4 5 6 7 8 9 10
$foo
[1] 1
$far
[1] 2
これは、画面にrの値を表示しようとしたときとまったく同じです。つまり、単一のブラケットを使用するとリストが返され、インデックス1に10要素のベクトルがあり、さらにfooという名前の要素が2つあります。そしてはるか。単一のブラケットへの入力として、単一のインデックスまたは要素名を指定することもできます。例えば:
> r[1]
[[1]]
[1] 1 2 3 4 5 6 7 8 9 10
この例では、1つのインデックス「1」を指定し、1つの要素(10個の数値の配列)を持つリストを返しました。
> r[2]
$foo
[1] 1
上記の例では、1つのインデックス「2」を指定し、代わりに1つの要素を持つリストを取得しました
> r["foo"];
$foo
[1] 1
この例では、1つの要素の名前を渡し、代わりに1つの要素のリストが返されました。
次のような要素名のベクトルを渡すこともできます:
> x<-c("foo","far")
> r[x];
$foo
[1] 1
$far
[1] 2
この例では、「foo」と「far」という2つの要素名を持つベクターを渡しました。
その代わり、2つの要素を持つリストを取得しました。
簡単に言えば、単一のブラケットは常に、単一のブラケットに渡す要素の数またはインデックスの数と等しい要素の数を持つ別のリストを返します。
対照的に、二重括弧は常に1つの要素のみを返します。ダブルブラケットに移動する前に、留意すべき点に注意してください。
NOTE:THE MAJOR DIFFERENCE BETWEEN THE TWO IS THAT SINGLE BRACKET RETURNS YOU A LIST WITH AS MANY ELEMENTS AS YOU WISH WHILE A DOUBLE BRACKET WILL NEVER RETURN A LIST. RATHER A DOUBLE BRACKET WILL RETURN ONLY A SINGLE ELEMENT FROM THE LIST.
いくつかの例を挙げます。太字の単語をメモしておいて、以下の例が終わったら、戻ってください。
二重括弧は、インデックスの実際の値を返します(リストは返しません)。
> r[[1]]
[1] 1 2 3 4 5 6 7 8 9 10
>r[["foo"]]
[1] 1
二重括弧の場合、ベクトルを渡して複数の要素を表示しようとすると、そのニーズに応えるために構築されたのではなく、単一の要素を返すためだけに構築されたため、エラーが発生します。
以下を検討してください
> r[[c(1:3)]]
Error in r[[c(1:3)]] : recursive indexing failed at level 2
> r[[c(1,2,3)]]
Error in r[[c(1, 2, 3)]] : recursive indexing failed at level 2
> r[[c("foo","far")]]
Error in r[[c("foo", "far")]] : subscript out of bounds
[]
1桁であってもリストクラスを返すという事実は非常に直感的ではありません。彼らは([])
リストのような別の構文を作成する必要があり[[]]
、実際の要素にアクセスすることは問題ありません。私[[]]
は他の言語のように生の価値と考えるのが好きです。
初心者が手動フォグをナビゲートできるようにするには、 [[ ... ]]
表記を折りたたみ関数としてつまり、名前付きベクター、リスト、またはデータフレームから「データを取得」するだけの場合です。これらのオブジェクトのデータを計算に使用する場合は、これを行うとよいでしょう。これらの簡単な例で説明します。
(x <- c(x=1, y=2)); x[1]; x[[1]]
(x <- list(x=1, y=2, z=3)); x[1]; x[[1]]
(x <- data.frame(x=1, y=2, z=3)); x[1]; x[[1]]
したがって、3番目の例から:
> 2 * x[1]
x
1 2
> 2 * x[[1]]
[1] 2
iris[[1]]
ベクトルをiris[1]
返しますが、data.frameを返します
さらに別の具体的な使用例として、split()
関数によって作成されたデータフレームを選択する場合は、二重括弧を使用します。わからない場合はsplit()
、リスト/データフレームをキーフィールドに基づいてサブセットにグループ化します。複数のグループを操作したり、それらをプロットしたりする場合に便利です。
> class(data)
[1] "data.frame"
> dsplit<-split(data, data$id)
> class(dsplit)
[1] "list"
> class(dsplit['ID-1'])
[1] "list"
> class(dsplit[['ID-1']])
[1] "data.frame"
以下の詳細な説明を参照してください。
mtcarsと呼ばれるRの組み込みデータフレームを使用しました。
> mtcars
mpg cyl disp hp drat wt ...
Mazda RX4 21.0 6 160 110 3.90 2.62 ...
Mazda RX4 Wag 21.0 6 160 110 3.90 2.88 ...
Datsun 710 22.8 4 108 93 3.85 2.32 ...
............
テーブルの一番上の行は、列名を含むヘッダーと呼ばれます。その後の各水平線はデータ行を示し、行の名前で始まり、その後に実際のデータが続きます。行の各データメンバーはセルと呼ばれます。
セルのデータを取得するには、単一の角かっこ「[]」演算子に行と列の座標を入力します。2つの座標はコンマで区切られます。つまり、座標は行の位置で始まり、その後にコンマが続き、列の位置で終わります。順序は重要です。
例1:-これは、mtcarsの最初の行、2番目の列のセル値です。
> mtcars[1, 2]
[1] 6
例2:-さらに、数値座標の代わりに行と列の名前を使用できます。
> mtcars["Mazda RX4", "cyl"]
[1] 6
二重の角括弧「[[]]」演算子を使用してデータフレーム列を参照します。
例1:組み込みデータセットmtcarsの9番目の列ベクトルを取得するには、mtcars [[9]]と記述します。
mtcars [[9]] [1] 1 1 1 0 0 0 0 0 0 0 0 ...
例2:-名前で同じ列ベクトルを取得できます。
mtcars [["am"]] [1] 1 1 1 0 0 0 0 0 0 0 0 ...