3 回答

TA貢獻1796條經驗 獲得超10個贊
兩種方法之間的顯著差異是它們在用于提取時返回的對象類,以及它們是否可以接受一系列值,或者在賦值期間只接受一個值。
考慮以下列表中的數據提取案例:
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'中的“裸”對象,該對象將具有適當的類:
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中的插槽保留了原始名稱。

TA貢獻1820條經驗 獲得超3個贊
雙括號訪問列表元素,而單個括號返回一個包含單個元素的列表。
lst <- list('one','two','three')
a <- lst[1]
class(a)
## returns "list"
a <- lst[[1]]
class(a)
## returns "character"
- 3 回答
- 0 關注
- 2091 瀏覽
添加回答
舉報