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中的插槽保留其原始名称。
来源:oschina
链接:https://my.oschina.net/u/3797416/blog/3159504