R提供了兩種不一樣的方法來訪問列表或data.frame的元素- []
和[[]]
運算符。 html
二者有什麼區別? 在什麼狀況下我應該使用另外一個? 函數
對於另外一個具體用例,當您要選擇split()
函數建立的數據框時,請使用雙括號。 若是您不知道, split()
基於一個關鍵字段將一個列表/數據幀分組爲子集。 若是要對多個組進行操做,繪製它們等,這將頗有用。 spa
> 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"
R語言定義可輕鬆回答如下類型的問題: code
R具備三個基本的索引運算符,其語法由如下示例顯示 orm
x[i] x[i, j] x[[i]] x[[i, j]] x$a x$"a"對於矢量和矩陣,
[[
形式]不多使用,儘管它們與[
形式有一些細微的語義差別(例如,它刪除了任何名稱或dimnames屬性,而且部分匹配用於字符索引)。 當索引多維結構與單一索引,x[[i]]
或x[i]
將返回i
的個時序元件x
。 htm對於列表,一般使用
[[
選擇任何單個元素,而[
返回所選元素的列表。 對象
[[
形式僅容許使用整數或字符索引選擇單個元素,而[
容許按向量進行索引。 請注意,儘管對於列表,索引能夠是一個向量,而且向量的每一個元素依次應用於列表,所選組件,該組件的所選組件,依此類推。 結果仍然是單個元素。 索引
雙括號訪問list 元素 ,而單括號則返回具備單個元素的列表。 three
lst <- list('one','two','three') a <- lst[1] class(a) ## returns "list" a <- lst[[1]] class(a) ## returns "character"
[]
提取列表, [[]]
提取列表中的元素 element
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"
兩種方法之間的顯着區別是,它們在提取時返回的對象的類別,以及它們是否能夠接受必定範圍的值,或者在賦值期間僅接受單個值。
考慮如下列表中數據提取的狀況:
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中的插槽保留其原始名稱。