列表(list)列表定義列表是一種特別的對象集合,它的元素也由序號(下標(biāo))區(qū)分,但是各元素的類型可以是任意對象,不同元素不必是同一類型。元素本身允許是其它復(fù)雜數(shù)據(jù)類型,比如,列表的一個元素也允許是列表。例如: > rec <- list(name="李明", age=30, scores=c(85, 76, 90)) > rec $name [1] "李明" $age [1] 30 $scores [1] 85 76 90列表元素總可以用“列表名[[下標(biāo)]]”的格式引用。例如: > rec[[2]] [1] 30 > rec[[3]][2] [1] 76但是,列表不同于向量,我們每次只能引用一個元素,如rec[[1:2]]的用法是不允許的。 注意:“列表名[下標(biāo)]”或“列表名[下標(biāo)范圍]”的用法也是合法的,但其意義與用兩重括號的記法完全不同,兩重記號取出列表的一個元素,結(jié)果與該元素類型相同,如果使用一重括號,則結(jié)果是列表的一個子列表(結(jié)果類型仍為列表)。 在定義列表時如果指定了元素的名字(如rec中的name,age,scores),則引用列表元素還可以用它的名字作為下標(biāo),格式為“列表名[["元素名"]]”,如: > rec[["age"]] [1] 30 另一種格式是“列表名$元素名”,如: > rec$age [1] 30 其中“元素名”可以簡寫到與其它元素名能夠區(qū)分的最短程度,比如“rec$s”可以代表 “rec$score”。這種寫法方便了交互運(yùn)行,編寫程序時一般不用簡寫以免降低程序的可讀性。 使用元素名的引用方法可以讓我們不必記住某一個下標(biāo)代表那一個元素,而直接用易記的元素名來引用元素。事實(shí)上,向量和矩陣也可以指定元素名、行名、列名。 定義列表使用list()函數(shù),每一個自變量變成列表的一個元素,自變量可以用“名字=值”的方式給出,即給出列表元素名。自變量的值被復(fù)制到列表元素中,自變量如果是變量并不會與該列表元素建立關(guān)系(改變該列表元素不會改變自變量的值)。 修改列表列表的元素可以修改,只要把元素引用賦值即可。如:> rec$age <- 45甚至 > rec$age <- list(19, 29, 31) (可以任意修改一個列表元素)。如果被賦值的元素原來不存在,則列表延伸以包含該新元素。例如,rec現(xiàn)在共有三個元素,我們定義一個新的命名元素,則列表長度變?yōu)?,再定義第六號元素則列表長度變?yōu)?: > rec$sex <- "男" > rec[[6]] <- 161 > rec $name [1] "李明" $age [1] 30 $scores [1] 85 76 90 $sex [1] "男" [[5]] NULL [[6]] [1] 161 第五號元素因?yàn)闆]有定義所有其值是“NULL”,這是空對象的記號。如果rec是一個向量,則其空元素為“NA”,這是缺失值的記號。從這里我們也可以體會“NULL”與“NA”的區(qū)別。 幾個列表可以用連接函數(shù)c()連接起來,結(jié)果仍為一個列表,其元素為各自變量的列表元素。如: > list.ABC <- c(list.A, list.B, list.C)(注意在S中句點(diǎn)是名字的合法部分,一般沒有特殊意義。) 幾個返回列表的函數(shù)列表的重要作用是把相關(guān)的若干數(shù)據(jù)保存在一個數(shù)據(jù)對象中,這樣在編寫函數(shù)時我們就可以返回這樣一個包含多項(xiàng)輸出的列表。因?yàn)楹瘮?shù)的返回結(jié)果可以完整地存放在一個列表中,我們可以繼續(xù)對得到的結(jié)果進(jìn)行分析,這是S比SAS靈活的一個地方。下面給出幾個返回列表的例子。 一、特征值和特征向量函數(shù)eigen(x)對對稱矩陣x計(jì)算其特征值和特征向量,返回結(jié)果為一個列表,列表的兩個成員(元素)為values和vectors。例如: > ev <- eigen((1:3) %o% (1:3)) > ev $values [1] 1.400000e+001 0.000000e+000-8.881784e-016 $vectors [,1] [,2] [,3] [1,] 0.2672612 0.8944272 -0.3585686 [2,] 0.5345225 -0.4472136 -0.7171372 [3,] 0.8017837 0.0000000 0.5976143 可見三個特征值只有第一個不為零(由于數(shù)值計(jì)算精度所限,第三個特征值應(yīng)為零但結(jié)果只是近似為零)。特征向量按矩陣存放,每一列為一個特征向量。 二、奇異值分解及行列式函數(shù)svd()進(jìn)行奇異值分解 ,其中 是任意 陣, 為 正交陣, 為 正交陣, 為 對角陣(只有主對角線元素不為零)。svd(x) 返回有三個成員d,u,v的列表,d為包含奇異值的向量(即 的主對角線元素),u,v分別為上面的兩個正交陣。 易見如果矩陣x是對稱陣則x的行列式的絕對值等于奇異值的乘積,所以: > absdetx <- prod(svd(x)$d) 或者我們可以為此定義一個函數(shù): > absdet <- function(x) prod(svd(x)$d) 三、最小二乘擬合與QR分解函數(shù)lsfit(x,y)返回最小二乘擬合的結(jié)果。最小二乘的模型為線性模型 lsfit(x,y)的第一個參數(shù)x為模型中的設(shè)計(jì)陣 ,第二個參數(shù)y為模型中的因變量y(可以是一個向量也可以是一個矩陣),返回一個列表,成員coefficients為上面模型的 (最小二乘系數(shù)),成員residuals為擬合殘差,成員intercept用來指示是否有截距項(xiàng),成員qr為設(shè)計(jì)陣 的QR分解,它本身也是一個列表。模型擬合缺省情況有截距項(xiàng),可以用intercept=FALSE選項(xiàng)指定無截距項(xiàng)。關(guān)于最小二乘擬合還可參見ls.diag() 函數(shù)(查看幫助)。 函數(shù)qr(x)返回x的QR分解結(jié)果。矩陣 的QR分解為 , 為對角線元素都等于1的下三角陣, 為上三角陣。函數(shù)結(jié)果為一個列表,成員qr 為一個矩陣,其上三角部分(包括對角線)分解的 ,其下三角部分(不包括對角線)為分解的 。其它成員為一些輔助信息。
|
|