方括号[]和双括号[[]]之间的区别是用于访问列表或数据框的元素

耗尽温柔 提交于 2020-02-25 18:48:29

R提供了两种不同的方法来访问列表或data.frame的元素- [][[]]运算符。

两者有什么区别? 在什么情况下我应该使用另一个?


#1楼

对于另一个具体用例,当您要选择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"

#2楼

R语言定义可轻松回答以下类型的问题:

R具有三个基本的索引运算符,其语法由以下示例显示

x[i] x[i, j] x[[i]] x[[i, j]] x$a x$"a"

对于矢量和矩阵, [[形式]很少使用,尽管它们与[形式有一些细微的语义差异(例如,它删除了任何名称或dimnames属性,并且部分匹配用于字符索引)。 当索引多维结构与单一索引, x[[i]]x[i]将返回i的个时序元件x

对于列表,通常使用[[选择任何单个元素,而[返回所选元素的列表。

[[形式仅允许使用整数或字符索引选择单个元素,而[允许按向量进行索引。 请注意,尽管对于列表,索引可以是一个向量,并且向量的每个元素依次应用于列表,所选组件,该组件的所选组件,依此类推。 结果仍然是单个元素。


#3楼

双括号访问list 元素 ,而单括号则返回具有单个元素的列表。

lst <- list('one','two','three')

a <- lst[1]
class(a)
## returns "list"

a <- lst[[1]]
class(a)
## returns "character"

#4楼

[]提取列表, [[]]提取列表中的元素

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楼

两种方法之间的显着区别是,它们在提取时返回的对象的类别,以及它们是否可以接受一定范围的值,或者在赋值期间仅接受单个值。

考虑以下列表中数据提取的情况:

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”中的“ bare”对象,该对象具有适当的类:

if( foo[[ 'bool' ]] ){ print("Hi!") }
[1] "Hi!"

class( foo[[ 'bool' ]] )
[1] "logical"

第二个区别是[]运算符可用于访问数据帧的列表或列中的一系列插槽,而[[]]运算符仅限于访问单个插槽或列。 考虑使用第二个列表bar()进行值分配的情况:

bar <- list( mat=matrix(0,nrow=2,ncol=2), rand=rnorm(1) )

假设我们想用bar中包含的数据覆盖foo的最后两个插槽。 如果我们尝试使用[[]]运算符,则会发生以下情况:

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中的插槽保留其原始名称。

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!