R 用于访问列表或数据帧元素的方括号[]和双括号[]之间的差异
R提供两种不同的方法来访问列表或数据框的元素:R 用于访问列表或数据帧元素的方括号[]和双括号[]之间的差异,r,list,dataframe,extract,r-faq,R,List,Dataframe,Extract,R Faq,R提供两种不同的方法来访问列表或数据框的元素:[]和[[]] 这两种语言的区别是什么?什么时候应该使用一种语言而不是另一种?R语言的定义对于回答这些类型的问题很方便: R有三个基本的索引运算符,下面的示例显示了语法 x[i] x[i,j] x[[i]] x[[i,j]] x$a x$“a” 对于向量和矩阵,很少使用[[表单,尽管它们与[表单有一些细微的语义差异(例如,它删除了任何名称或dimnames属性,并且部分匹配用于字符索引)。当使用单个索引索引多维结构时,x[[i]或x[
[]
和[[]]
这两种语言的区别是什么?什么时候应该使用一种语言而不是另一种?R语言的定义对于回答这些类型的问题很方便:
x[i]
x[i,j]
x[[i]]
x[[i,j]]
x$a
x$“a”
对于向量和矩阵,很少使用[[
表单,尽管它们与[
表单有一些细微的语义差异(例如,它删除了任何名称或dimnames属性,并且部分匹配用于字符索引)。当使用单个索引索引多维结构时,x[[i]
或x[i]
将返回i
x的第个顺序元素。
对于列表,通常使用[
选择任何单个元素,而[
返回所选元素的列表。
[[
表单只允许使用整数或字符索引选择单个元素,而[
允许通过向量进行索引。请注意,对于列表,索引可以是向量,向量的每个元素依次应用于列表、选定组件、该组件的选定组件等。结果仍然是单个元素。
双括号访问一个列表元素,而单括号返回一个包含单个元素的列表
lst <- list('one','two','three')
a <- lst[1]
class(a)
## returns "list"
a <- lst[[1]]
class(a)
## returns "character"
lst[]
提取列表,[[]]
提取列表中的元素
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"
alist这两种方法之间的显著区别在于它们在用于提取时返回的对象的类别,以及它们在赋值过程中是接受一系列值,还是只接受一个值
考虑以下列表中的数据提取情况:
foo <- list( str='R', vec=c(1,2,3), bool=TRUE )
这是因为[]
方法返回了一个列表,而列表不是有效的对象,无法直接传递到if()
语句中。在这种情况下,我们需要使用[[]]
,因为它将返回存储在“bool”中的“bare”对象,该对象将具有适当的类:
if( foo[[ 'bool' ]] ){ print("Hi!") }
[1] "Hi!"
class( foo[[ 'bool' ]] )
[1] "logical"
第二个区别是,使用<代码> []/Cord>运算符可以访问数据帧中的列表或列中的“<强>范围< /强>”,而<代码> []]/Cord>运算符仅限于访问<强>单< /强>槽或列。考虑使用第二个列表的值赋值的情况,<代码> BAL():<代码>:
这是因为[[]]
仅限于访问单个元素。我们需要使用[]
:
foo[ 2:3 ] <- bar
print( foo )
$str
[1] "R"
$vec
[,1] [,2]
[1,] 0 0
[2,] 0 0
$bool
[1] -0.6291121
foo[2:3]对于另一个具体的用例,当您想要选择由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"
>类(数据)
[1] “数据帧”
>dsplit类(dsplit)
[1] “列表”
>类(dsplit['ID-1'])
[1] “列表”
>类(dsplit['ID-1']]
[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]]
两者都是细分的方式。
单括号将返回列表的一个子集,它本身就是一个列表。即:它可能包含也可能不包含多个元素。
另一方面,双括号将只返回列表中的单个元素
-单括号将为我们提供一个列表。如果我们希望从列表中返回多个元素,也可以使用单括号。
考虑下面的列表:-
>r<-list(c(1:10),foo=1,far=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和far的元素。
我们也可以选择提供一个索引或元素名作为单括号的输入。
例如:
在本例中,我们给出了一个索引“1”,作为回报,得到了一个包含一个元素的列表(这是一个由10个数字组成的数组)
在上面的示例中,我们给出了一个索引“2”,作为回报,得到了一个包含一个元素的列表
> r["foo"];
$foo
[1] 1
在本例中,我们传递了一个元素的名称,作为回报,返回了一个包含一个元素的列表
lst <- list('one','two','three')
a <- lst[1]
class(a)
## returns "list"
a <- lst[[1]]
class(a)
## returns "character"
还可以传递元素名称向量,如:-
> x<-c("foo","far")
> r[x];
$foo
[1] 1
$far
[1] 2
对于双括号,如果我们试图通过传递一个向量来查看多个元素,它将导致错误,因为它不是为了满足这种需要而构建的,而只是为了返回单个元素。
考虑以下几点
> 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
只需在这里添加[[
也可用于递归索引
这一点在@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
回到上面@JijoMatthew的答案,回想一下r
:
r <- list(1:10, foo=1, far=2)
r[[1:3]]
中出错:递归索引在级别2失败
由于此代码实际上试图计算r[[1][[2][[3]]
,
> r[2]
$foo
[1] 1
> r["foo"];
$foo
[1] 1
> x<-c("foo","far")
> r[x];
$foo
[1] 1
$far
[1] 2
> 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
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
x[[c(2, 1, 1, 1)]]
# [1] 3
r <- list(1:10, foo=1, far=2)
r[[1:3]]
> 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 ...
............
> mtcars[1, 2]
[1] 6
> mtcars["Mazda RX4", "cyl"]
[1] 6
df1 <- data.frame(a = 1:3)
df1$b <- list(4:5, 6:7, 8:9)
df1[[1,2]]
df1[1,2]
str(df1[[1,2]])
str(df1[1,2])