R provides two different methods for accessing the elements of a list or data.frame- the []
and [[]]
operators.
R为访问列表或数据的元素提供了两种不同的方法——[]和[]运算符。
What is the difference between the two? In what situations should I use one over the other?
这两者之间有什么区别?在什么情况下我应该使用一个而不是另一个?
10 个解决方案
#1
260
The R Language Definition is handy for answering these types of questions:
R语言的定义可以方便地回答这类问题:
- http://cran.r-project.org/doc/manuals/R-lang.html#Indexing
- http://cran.r-project.org/doc/manuals/R-lang.html索引
R has three basic indexing operators, with syntax displayed by the following examples
R有三个基本的索引操作符,下面的示例显示了语法
x[i] x[i, j] x[[i]] x[[i, j]] x$a x$"a"
For vectors and matrices the
[[
forms are rarely used, although they have some slight semantic differences from the [ form (e.g. it drops any names or dimnames attribute, and that partial matching is used for character indices). When indexing multi-dimensional structures with a single index,x[[i]]
orx[i]
will return thei
th sequential element ofx
.对于向量和矩阵,[[表单很少使用,尽管它们与[表单有一些细微的语义差异(例如,它删除任何名称或dimnames属性,并且部分匹配用于字符索引)。当具有单个索引的多维结构时,x[i]或x[i]将返回x的第i个序列元素。
For lists, one generally uses
[[
to select any single element, whereas[
returns a list of the selected elements.对于列表,通常使用[来选择任何单个元素,而[则返回所选元素的列表。
The
[[
form allows only a single element to be selected using integer or character indices, whereas[
allows indexing by vectors. Note though that for a list, the index can be a vector and each element of the vector is applied in turn to the list, the selected component, the selected component of that component, and so on. The result is still a single element.[表单只允许使用整数或字符索引选择单个元素,而[则允许按向量进行索引。注意,对于一个列表,索引可以是一个向量,而向量的每个元素依次被应用到列表、所选组件、该组件的选定组件,等等。结果仍然是一个元素。
#2
144
The significant differences between the two methods are the class of the objects they return when used for extraction and whether they may accept a range of values, or just a single value during assignment.
这两种方法之间的显著区别在于它们用于提取时返回的对象的类,以及它们是否可以接受一个值范围,或者在赋值时只接受一个值。
Consider the case of data extraction on the following list:
考虑以下列表中的数据提取情况:
foo <- list( str='R', vec=c(1,2,3), bool=TRUE )
Say we would like to extract the value stored by bool from foo and use it inside an if()
statement. This will illustrate the differences between the return values of []
and [[]]
when they are used for data extraction. The []
method returns objects of class list (or data.frame if foo was a data.frame) while the [[]]
method returns objects whose class is determined by the type of their values.
假设我们想从foo中提取bool存储的值,并在if()语句中使用它。这将说明用于数据提取的[]和[]的返回值之间的差异。方法返回类列表的对象(如果foo是data.frame,则返回data.frame),而方法返回的对象的类由其值的类型决定。
So, using the []
method results in the following:
因此,使用[]方法可以得到以下结果:
if( foo[ 'bool' ] ){ print("Hi!") }
Error in if (foo["bool"]) { : argument is not interpretable as logical
class( foo[ 'bool' ] )
[1] "list"
This is because the []
method returned a list and a list is not valid object to pass directly into an if()
statement. In this case we need to use [[]]
because it will return the "bare" object stored in 'bool' which will have the appropriate class:
这是因为[]方法返回一个列表,而列表不是直接传递到if()语句的有效对象。在这种情况下,我们需要使用[[]],因为它将返回存储在'bool'中的“裸”对象,该对象将具有适当的类:
if( foo[[ 'bool' ]] ){ print("Hi!") }
[1] "Hi!"
class( foo[[ 'bool' ]] )
[1] "logical"
The second difference is that the []
operator may be used to access a range of slots in a list or columns in a data frame while the [[]]
operator is limited to accessing a single slot or column. Consider the case of value assignment using a second list, bar()
:
第二个区别是[]操作符可用于访问数据帧中的列表或列中的一系列插槽,而[[]]操作符只能访问单个的槽或列。考虑使用第二个列表bar()分配值的情况:
bar <- list( mat=matrix(0,nrow=2,ncol=2), rand=rnorm(1) )
Say we want to overwrite the last two slots of foo with the data contained in bar. If we try to use the [[]]
operator, this is what happens:
假设我们要用bar中包含的数据覆盖foo的最后两个槽。如果我们尝试使用[]运算符,会发生以下情况:
foo[[ 2:3 ]] <- bar
Error in foo[[2:3]] <- bar :
more elements supplied than there are to replace
This is because [[]]
is limited to accessing a single element. We need to use []
:
这是因为[]仅限于访问单个元素。我们需要使用[]:
foo[ 2:3 ] <- bar
print( foo )
$str
[1] "R"
$vec
[,1] [,2]
[1,] 0 0
[2,] 0 0
$bool
[1] -0.6291121
Note that while the assignment was successful, the slots in foo kept their original names.
请注意,当分配成功时,foo中的slot保留其原始名称。
#3
89
Double brackets accesses a list element, while a single bracket gives you back a list with a single element.
双括号访问列表元素,而单个括号将返回一个包含单个元素的列表。
lst <- list('one','two','three')
a <- lst[1]
class(a)
## returns "list"
a <- lst[[1]]
class(a)
## returns "character"
#4
38
[]
extracts a list, [[]]
extracts elements within the list
[]提取列表,[]提取列表中的元素
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"
#5
14
Just adding here that [[
also is equipped for recursive indexing.
只要在这里加上[[也是用于递归索引的。
This was hinted at in the answer by @JijoMatthew but not explored.
这在@JijoMatthew的答案中被暗示,但未被探究。
As noted in ?"[["
, syntax like x[[y]]
, where length(y) > 1
, is interpreted as:
如在?"["中所述,如x[[y]的语法中,长度(y) > 1被解释为:
x[[ y[1] ]][[ y[2] ]][[ y[3] ]] ... [[ y[length(y)] ]]
Note that this doesn't change what should be your main takeaway on the difference between [
and [[
-- namely, that the former is used for subsetting, and the latter is used for extracting single list elements.
注意,这并没有改变[和[]之间的主要区别——即前者用于子设置,后者用于提取单个列表元素。
For example,
例如,
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
To get the value 3, we can do:
要得到值3,我们可以:
x[[c(2, 1, 1, 1)]]
# [1] 3
Getting back to @JijoMatthew's answer above, recall r
:
回到上面@JijoMatthew的答案:
r <- list(1:10, foo=1, far=2)
In particular, this explains the errors we tend to get when mis-using [[
, namely:
特别地,这解释了我们在误用[[]时容易出现的错误,即:
r[[1:3]]
Error in
r[[1:3]]
: recursive indexing failed at level 2r中的错误[1:3]:递归索引在第2级失败
Since this code actually tried to evaluate r[[1]][[2]][[3]]
, and the nesting of r
stops at level one, the attempt to extract through recursive indexing failed at [[2]]
, i.e., at level 2.
由于这段代码实际上试图求出r[[1]][[2]][[3]],并且r的嵌套在第一级时停止,所以在[[2]][[2]]上尝试递归提取失败,即。2级。
Error in
r[[c("foo", "far")]]
: subscript out of boundsr[[c("foo", "far")]中的错误:下标越界
Here, R was looking for r[["foo"]][["far"]]
, which doesn't exist, so we get the subscript out of bounds error.
在这里,R在寻找R [[[]]][[far]],这是不存在的,所以我们得到了边界错误的下标。
It probably would be a bit more helpful/consistent if both of these errors gave the same message.
如果这两个错误都给出了相同的信息,那么它可能会更有帮助。
#6
12
Both of them are ways of subsetting. The single bracket will will return a subset of the list, which in itself will be a list. ie:It may or may not contain more than one elements. On the other hand a double bracket will return just a single element from the list.
它们都是子设置的方式。单括号将返回列表的一个子集,它本身就是一个列表。ie:它可能包含或不包含多个元素。另一方面,双括号只返回列表中的一个元素。
-Single bracket will give us a list. We can also use single bracket if we wish to return multiple elements from the list. consider the following list:-
-单括号会给我们一个列表。如果希望从列表中返回多个元素,也可以使用单括号。考虑下面的列表:-
>r<-list(c(1:10),foo=1,far=2);
Now please note the way the list is returned when I try to display it. I type r and press enter
现在请注意当我试图显示列表时返回列表的方式。输入r,按回车键
>r
#the result is:-
[[1]]
[1] 1 2 3 4 5 6 7 8 9 10
$foo
[1] 1
$far
[1] 2
Now we will see the magic of single bracket:-
现在我们将看到单括号的魔力:-
>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
which is exactly the same as when we tried to display value of r on screen, which means the usage of single bracket has returned a list, where at index 1 we have a vector of 10 elements, then we have two more elements with names foo and far. We may also choose to give a single index or element name as input to the single bracket. eg:
这和我们在屏幕上显示r的值是一样的,这意味着使用单括号返回了一个列表,在索引1我们有一个包含10个元素的向量,然后我们还有两个元素,名字是foo和far。我们也可以选择将一个索引或元素名称作为单个括号的输入。例如:
> r[1]
[[1]]
[1] 1 2 3 4 5 6 7 8 9 10
In this example we gave one index "1" and in return got a list with one element(which is an array of 10 numbers)
在本例中,我们给出了一个索引“1”,然后返回一个包含一个元素的列表(这是一个10个数字的数组)
> r[2]
$foo
[1] 1
In the above example we gave one index "2" and in return got a list with one element
在上面的例子中,我们给出了一个索引“2”,然后返回一个包含一个元素的列表。
> r["foo"];
$foo
[1] 1
In this example we passed the name of one element and in return a list was returned with one element.
在本例中,我们传递了一个元素的名称,作为回报,一个列表返回了一个元素。
You may also pass a vector of element names like:-
您还可以传递元素名称的向量,如:-
> x<-c("foo","far")
> r[x];
$foo
[1] 1
$far
[1] 2
In this example we passed an vector with two element names "foo" and "far"
在本例中,我们传递了一个带有两个元素名“foo”和“far”的向量
In return we got a list with two elements.
作为回报,我们得到了一个包含两个元素的列表。
In short single bracket will always return you another list with number of elements equal to the number of elements or number of indices you pass into the single bracket.
在短的单括号中,总是会返回另一个列表,其中元素的数量等于您传入单括号中的元素的数量或索引的数量。
In contrast, a double bracket will always return only one element. Before moving to double bracket a note to be kept in mind. 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.
相反,双括号总是只返回一个元素。在移动到双括号之前,要记住一个注意事项。注意:两者之间的主要区别是,单括号返回一个列表,其中包含您希望的所有元素,而双括号永远不会返回一个列表。相反,双括号只返回列表中的单个元素。
I will site a few examples. Please keep a note of the words in bold and come back to it after you are done with the examples below:
我将举出几个例子。请把这些粗体的单词记下来,用完下面的例子后再回来:
Double bracket will return you the actual value at the index.(It will NOT return a list)
双括号将返回索引处的实际值。(它不会返回一个列表)
> r[[1]]
[1] 1 2 3 4 5 6 7 8 9 10
>r[["foo"]]
[1] 1
for double brackets if we try to view more than one elements by passing a vector it will result in an error just because it was not built to cater to that need, but just to return a single element.
对于双括号,如果我们通过传递一个向量来查看多个元素,它会导致一个错误,因为它不是为了满足这个需要而构建的,而是为了返回一个元素。
Consider the following
考虑以下
> 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
#7
11
To help newbies navigate through the manual fog, it might be helpful to see the [[ ... ]]
notation as a collapsing function - in other words, it is when you just want to 'get the data' from a named vector, list or data frame. It is good to do this if you want to use data from these objects for calculations. These simple examples will illustrate.
为了帮助新手在手动雾中导航,看一下[……]符号作为一个崩溃的函数——换句话说,就是当你只想从一个指定的向量、列表或数据框中“获取数据”的时候。如果您想要使用这些对象的数据进行计算,那么这样做是很好的。这些简单的例子将说明这一点。
(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]]
So from the third example:
从第三个例子来看
> 2 * x[1]
x
1 2
> 2 * x[[1]]
[1] 2
#8
#9
7
For yet another concrete use case, use double brackets when you want to select a data frame created by the split()
function. If you don't know, split()
groups a list/data frame into subsets based on a key field. It's useful if when you want to operate on multiple groups, plot them, etc.
对于另一个具体的用例,当您想要选择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"
#10
5
Being terminological, [[
operator extracts the element from a list whereas [
operator takes subset of a list.
作为术语,[操作符从列表中提取元素,而[操作符获取列表的子集。
#1
260
The R Language Definition is handy for answering these types of questions:
R语言的定义可以方便地回答这类问题:
- http://cran.r-project.org/doc/manuals/R-lang.html#Indexing
- http://cran.r-project.org/doc/manuals/R-lang.html索引
R has three basic indexing operators, with syntax displayed by the following examples
R有三个基本的索引操作符,下面的示例显示了语法
x[i] x[i, j] x[[i]] x[[i, j]] x$a x$"a"
For vectors and matrices the
[[
forms are rarely used, although they have some slight semantic differences from the [ form (e.g. it drops any names or dimnames attribute, and that partial matching is used for character indices). When indexing multi-dimensional structures with a single index,x[[i]]
orx[i]
will return thei
th sequential element ofx
.对于向量和矩阵,[[表单很少使用,尽管它们与[表单有一些细微的语义差异(例如,它删除任何名称或dimnames属性,并且部分匹配用于字符索引)。当具有单个索引的多维结构时,x[i]或x[i]将返回x的第i个序列元素。
For lists, one generally uses
[[
to select any single element, whereas[
returns a list of the selected elements.对于列表,通常使用[来选择任何单个元素,而[则返回所选元素的列表。
The
[[
form allows only a single element to be selected using integer or character indices, whereas[
allows indexing by vectors. Note though that for a list, the index can be a vector and each element of the vector is applied in turn to the list, the selected component, the selected component of that component, and so on. The result is still a single element.[表单只允许使用整数或字符索引选择单个元素,而[则允许按向量进行索引。注意,对于一个列表,索引可以是一个向量,而向量的每个元素依次被应用到列表、所选组件、该组件的选定组件,等等。结果仍然是一个元素。
#2
144
The significant differences between the two methods are the class of the objects they return when used for extraction and whether they may accept a range of values, or just a single value during assignment.
这两种方法之间的显著区别在于它们用于提取时返回的对象的类,以及它们是否可以接受一个值范围,或者在赋值时只接受一个值。
Consider the case of data extraction on the following list:
考虑以下列表中的数据提取情况:
foo <- list( str='R', vec=c(1,2,3), bool=TRUE )
Say we would like to extract the value stored by bool from foo and use it inside an if()
statement. This will illustrate the differences between the return values of []
and [[]]
when they are used for data extraction. The []
method returns objects of class list (or data.frame if foo was a data.frame) while the [[]]
method returns objects whose class is determined by the type of their values.
假设我们想从foo中提取bool存储的值,并在if()语句中使用它。这将说明用于数据提取的[]和[]的返回值之间的差异。方法返回类列表的对象(如果foo是data.frame,则返回data.frame),而方法返回的对象的类由其值的类型决定。
So, using the []
method results in the following:
因此,使用[]方法可以得到以下结果:
if( foo[ 'bool' ] ){ print("Hi!") }
Error in if (foo["bool"]) { : argument is not interpretable as logical
class( foo[ 'bool' ] )
[1] "list"
This is because the []
method returned a list and a list is not valid object to pass directly into an if()
statement. In this case we need to use [[]]
because it will return the "bare" object stored in 'bool' which will have the appropriate class:
这是因为[]方法返回一个列表,而列表不是直接传递到if()语句的有效对象。在这种情况下,我们需要使用[[]],因为它将返回存储在'bool'中的“裸”对象,该对象将具有适当的类:
if( foo[[ 'bool' ]] ){ print("Hi!") }
[1] "Hi!"
class( foo[[ 'bool' ]] )
[1] "logical"
The second difference is that the []
operator may be used to access a range of slots in a list or columns in a data frame while the [[]]
operator is limited to accessing a single slot or column. Consider the case of value assignment using a second list, bar()
:
第二个区别是[]操作符可用于访问数据帧中的列表或列中的一系列插槽,而[[]]操作符只能访问单个的槽或列。考虑使用第二个列表bar()分配值的情况:
bar <- list( mat=matrix(0,nrow=2,ncol=2), rand=rnorm(1) )
Say we want to overwrite the last two slots of foo with the data contained in bar. If we try to use the [[]]
operator, this is what happens:
假设我们要用bar中包含的数据覆盖foo的最后两个槽。如果我们尝试使用[]运算符,会发生以下情况:
foo[[ 2:3 ]] <- bar
Error in foo[[2:3]] <- bar :
more elements supplied than there are to replace
This is because [[]]
is limited to accessing a single element. We need to use []
:
这是因为[]仅限于访问单个元素。我们需要使用[]:
foo[ 2:3 ] <- bar
print( foo )
$str
[1] "R"
$vec
[,1] [,2]
[1,] 0 0
[2,] 0 0
$bool
[1] -0.6291121
Note that while the assignment was successful, the slots in foo kept their original names.
请注意,当分配成功时,foo中的slot保留其原始名称。
#3
89
Double brackets accesses a list element, while a single bracket gives you back a list with a single element.
双括号访问列表元素,而单个括号将返回一个包含单个元素的列表。
lst <- list('one','two','three')
a <- lst[1]
class(a)
## returns "list"
a <- lst[[1]]
class(a)
## returns "character"
#4
38
[]
extracts a list, [[]]
extracts elements within the list
[]提取列表,[]提取列表中的元素
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"
#5
14
Just adding here that [[
also is equipped for recursive indexing.
只要在这里加上[[也是用于递归索引的。
This was hinted at in the answer by @JijoMatthew but not explored.
这在@JijoMatthew的答案中被暗示,但未被探究。
As noted in ?"[["
, syntax like x[[y]]
, where length(y) > 1
, is interpreted as:
如在?"["中所述,如x[[y]的语法中,长度(y) > 1被解释为:
x[[ y[1] ]][[ y[2] ]][[ y[3] ]] ... [[ y[length(y)] ]]
Note that this doesn't change what should be your main takeaway on the difference between [
and [[
-- namely, that the former is used for subsetting, and the latter is used for extracting single list elements.
注意,这并没有改变[和[]之间的主要区别——即前者用于子设置,后者用于提取单个列表元素。
For example,
例如,
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
To get the value 3, we can do:
要得到值3,我们可以:
x[[c(2, 1, 1, 1)]]
# [1] 3
Getting back to @JijoMatthew's answer above, recall r
:
回到上面@JijoMatthew的答案:
r <- list(1:10, foo=1, far=2)
In particular, this explains the errors we tend to get when mis-using [[
, namely:
特别地,这解释了我们在误用[[]时容易出现的错误,即:
r[[1:3]]
Error in
r[[1:3]]
: recursive indexing failed at level 2r中的错误[1:3]:递归索引在第2级失败
Since this code actually tried to evaluate r[[1]][[2]][[3]]
, and the nesting of r
stops at level one, the attempt to extract through recursive indexing failed at [[2]]
, i.e., at level 2.
由于这段代码实际上试图求出r[[1]][[2]][[3]],并且r的嵌套在第一级时停止,所以在[[2]][[2]]上尝试递归提取失败,即。2级。
Error in
r[[c("foo", "far")]]
: subscript out of boundsr[[c("foo", "far")]中的错误:下标越界
Here, R was looking for r[["foo"]][["far"]]
, which doesn't exist, so we get the subscript out of bounds error.
在这里,R在寻找R [[[]]][[far]],这是不存在的,所以我们得到了边界错误的下标。
It probably would be a bit more helpful/consistent if both of these errors gave the same message.
如果这两个错误都给出了相同的信息,那么它可能会更有帮助。
#6
12
Both of them are ways of subsetting. The single bracket will will return a subset of the list, which in itself will be a list. ie:It may or may not contain more than one elements. On the other hand a double bracket will return just a single element from the list.
它们都是子设置的方式。单括号将返回列表的一个子集,它本身就是一个列表。ie:它可能包含或不包含多个元素。另一方面,双括号只返回列表中的一个元素。
-Single bracket will give us a list. We can also use single bracket if we wish to return multiple elements from the list. consider the following list:-
-单括号会给我们一个列表。如果希望从列表中返回多个元素,也可以使用单括号。考虑下面的列表:-
>r<-list(c(1:10),foo=1,far=2);
Now please note the way the list is returned when I try to display it. I type r and press enter
现在请注意当我试图显示列表时返回列表的方式。输入r,按回车键
>r
#the result is:-
[[1]]
[1] 1 2 3 4 5 6 7 8 9 10
$foo
[1] 1
$far
[1] 2
Now we will see the magic of single bracket:-
现在我们将看到单括号的魔力:-
>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
which is exactly the same as when we tried to display value of r on screen, which means the usage of single bracket has returned a list, where at index 1 we have a vector of 10 elements, then we have two more elements with names foo and far. We may also choose to give a single index or element name as input to the single bracket. eg:
这和我们在屏幕上显示r的值是一样的,这意味着使用单括号返回了一个列表,在索引1我们有一个包含10个元素的向量,然后我们还有两个元素,名字是foo和far。我们也可以选择将一个索引或元素名称作为单个括号的输入。例如:
> r[1]
[[1]]
[1] 1 2 3 4 5 6 7 8 9 10
In this example we gave one index "1" and in return got a list with one element(which is an array of 10 numbers)
在本例中,我们给出了一个索引“1”,然后返回一个包含一个元素的列表(这是一个10个数字的数组)
> r[2]
$foo
[1] 1
In the above example we gave one index "2" and in return got a list with one element
在上面的例子中,我们给出了一个索引“2”,然后返回一个包含一个元素的列表。
> r["foo"];
$foo
[1] 1
In this example we passed the name of one element and in return a list was returned with one element.
在本例中,我们传递了一个元素的名称,作为回报,一个列表返回了一个元素。
You may also pass a vector of element names like:-
您还可以传递元素名称的向量,如:-
> x<-c("foo","far")
> r[x];
$foo
[1] 1
$far
[1] 2
In this example we passed an vector with two element names "foo" and "far"
在本例中,我们传递了一个带有两个元素名“foo”和“far”的向量
In return we got a list with two elements.
作为回报,我们得到了一个包含两个元素的列表。
In short single bracket will always return you another list with number of elements equal to the number of elements or number of indices you pass into the single bracket.
在短的单括号中,总是会返回另一个列表,其中元素的数量等于您传入单括号中的元素的数量或索引的数量。
In contrast, a double bracket will always return only one element. Before moving to double bracket a note to be kept in mind. 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.
相反,双括号总是只返回一个元素。在移动到双括号之前,要记住一个注意事项。注意:两者之间的主要区别是,单括号返回一个列表,其中包含您希望的所有元素,而双括号永远不会返回一个列表。相反,双括号只返回列表中的单个元素。
I will site a few examples. Please keep a note of the words in bold and come back to it after you are done with the examples below:
我将举出几个例子。请把这些粗体的单词记下来,用完下面的例子后再回来:
Double bracket will return you the actual value at the index.(It will NOT return a list)
双括号将返回索引处的实际值。(它不会返回一个列表)
> r[[1]]
[1] 1 2 3 4 5 6 7 8 9 10
>r[["foo"]]
[1] 1
for double brackets if we try to view more than one elements by passing a vector it will result in an error just because it was not built to cater to that need, but just to return a single element.
对于双括号,如果我们通过传递一个向量来查看多个元素,它会导致一个错误,因为它不是为了满足这个需要而构建的,而是为了返回一个元素。
Consider the following
考虑以下
> 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
#7
11
To help newbies navigate through the manual fog, it might be helpful to see the [[ ... ]]
notation as a collapsing function - in other words, it is when you just want to 'get the data' from a named vector, list or data frame. It is good to do this if you want to use data from these objects for calculations. These simple examples will illustrate.
为了帮助新手在手动雾中导航,看一下[……]符号作为一个崩溃的函数——换句话说,就是当你只想从一个指定的向量、列表或数据框中“获取数据”的时候。如果您想要使用这些对象的数据进行计算,那么这样做是很好的。这些简单的例子将说明这一点。
(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]]
So from the third example:
从第三个例子来看
> 2 * x[1]
x
1 2
> 2 * x[[1]]
[1] 2
#8
10
From Hadley Wickham:
从哈德利韦翰:
My (crappy looking) modification to show using tidyverse / purrr:
用tidyverse / purrr修改我的(蹩脚的外观):
#9
7
For yet another concrete use case, use double brackets when you want to select a data frame created by the split()
function. If you don't know, split()
groups a list/data frame into subsets based on a key field. It's useful if when you want to operate on multiple groups, plot them, etc.
对于另一个具体的用例,当您想要选择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"
#10
5
Being terminological, [[
operator extracts the element from a list whereas [
operator takes subset of a list.
作为术语,[操作符从列表中提取元素,而[操作符获取列表的子集。