簡介
R語言是一套開源的數(shù)據(jù)分析解決方案。R語言中提供了多種存儲數(shù)據(jù)的對象類型潮改,包括標(biāo)量(R語言中的標(biāo)量是由向量的形式表示狭郑,可以說R語言沒有標(biāo)量),向量汇在,矩陣翰萨,數(shù)組,數(shù)據(jù)框糕殉,列表還有因子(與前幾者并非完全獨立)亩鬼。作為初學(xué)者,我主要關(guān)注這些結(jié)構(gòu)的三個方面:創(chuàng)建阿蝶,取值雳锋,額外的問題。
1.“標(biāo)量”
所謂的標(biāo)量就是只含一個元素的向量羡洁,多用于儲存常量玷过。示例如下:
> c <- 3
> c
[1] 3
可以看出來c是一個只存儲了1個元素的向量。
2.向量
向量是用于儲存數(shù)值型,字符型或者邏輯型的一維數(shù)組辛蚊。數(shù)組中的值類型必須保持一致粤蝎。最常見的創(chuàng)建向量的方式是通過函數(shù) : c( ) 。值得注意的是袋马,R的下標(biāo)不從0開始而從1開始初澎。
> #create a vector
> #vector(mode = "logical", length = 0)
> #c()
> v <- c(11,22,33,44,55,66)
> v
[1] 11 22 33 44 55 66
向量的創(chuàng)建
可以使用冒號生成數(shù)值序列來創(chuàng)建
> v <- c(1:5)
> v
[1] 1 2 3 4 5
也可以結(jié)合運算表達式來創(chuàng)建
> v <- c(1:5*3)
> v
[1] 3 6 9 12 15
有趣的是,下面這種寫法的結(jié)果和上面的大相徑庭虑凛,不僅僅是數(shù)值的大小上碑宴,原因與運算順序有關(guān),在此不再多敘卧檐。
v <- c(1:5**3)
獲取值的方式
通過下標(biāo)獲饶苟:
> v[3]
[1] 9
通過c函數(shù)的下標(biāo)序列獲取:
> v[c(1,3,5)]
[1] 3 9 15
通過等值序列獲让骨簟:
> v[2:4]
[1] 6 9 12
通過c函數(shù)和等值序列獲炔蹲小:
> v[c(1:3)]
[1] 3 6 9
也可以結(jié)合一些運算獲得值,在此不一一列舉盈罐。
一些特殊情況
想要獲得下標(biāo)為0的元素不會報錯榜跌,不會返回值:
> v[0]
numeric(0)
越界也不會報錯,會返回NA(不存在的值):
> v[7]
[1] NA
使用等值序列的下標(biāo)獲得值時可以顛倒順序盅粪,而且不會報錯:
> v[7:2]
[1] NA NA 15 12 9 6
但是如果冒號左右缺失數(shù)據(jù)便會報錯:
#錯誤的方式
v[3:]
v[:]
v[:2]
這些也是與Python的數(shù)組以及NumPy數(shù)組有區(qū)別的地方钓葫。
3.矩陣
矩陣其實是一個二維數(shù)組。一般創(chuàng)建格式為:
matrix(data = NA, nrow = 1, ncol = 1, byrow = FALSE,dimnames = NULL)
矩陣的創(chuàng)建
可以使用數(shù)學(xué)表達式或者等值序列進行創(chuàng)建票顾。
> x <- matrix (1*2:11*2,nrow = 2)
> x
[,1] [,2] [,3] [,4] [,5]
[1,] 4 8 12 16 20
[2,] 6 10 14 18 22
矩陣的創(chuàng)建默認(rèn)是按列填充础浮,將矩陣創(chuàng)建函數(shù)中的參數(shù)設(shè)為byrow = TRUE便可按行填充。dimnames用于聲明行列名奠骄。參數(shù)位置不作要求豆同。示例如下:
> x <- matrix (1:10,nrow = 2,ncol =5,dimnames = list (c("R1","R2"),c("C1","C2","C3","C4","C5")),byrow =TRUE)
> x
C1 C2 C3 C4 C5
R1 1 2 3 4 5
R2 6 7 8 9 10
有趣的是,創(chuàng)建時規(guī)定了具體的nrow與ncol數(shù)值后如果實際傳入的數(shù)值數(shù)小于nrow * ncol,則會用傳入的值循環(huán)補上缺少的位置,但是會產(chǎn)生警告:
> x <- matrix (1*2:8*2,nrow = 2,ncol =5,dimnames = list (c("R1","R2"),c("C1","C2","C3","C4","C5")))
Warning message:
In matrix(1 * 2:8 * 2, nrow = 2, ncol = 5, dimnames = list(c("R1", :
數(shù)據(jù)長度[7]不是矩陣行數(shù)[2]的整倍
> x
C1 C2 C3 C4 C5
R1 4 8 12 16 6
R2 6 10 14 4 8
獲取值的方式
以該矩陣為例:
> x <- matrix (1:10,nrow = 2,dimnames = list (c("R1","R2"),c("C1","C2","C3","C4","C5")))
> x
C1 C2 C3 C4 C5
R1 1 3 5 7 9
R2 2 4 6 8 10
單下標(biāo)獲群邸:根據(jù)所有數(shù)值中該值的位置獲取
x[2]
[1] 2
雙下標(biāo)獲扔靶狻:根據(jù)二維坐標(biāo)獲取
> x[2,3]
[1] 6
結(jié)合c函數(shù)下標(biāo)序列:
> x[1,c(3,5)]
C3 C5
5 9
結(jié)合等值序列:
> x[1,c(3:5)]
C3 C4 C5
5 7 9
獲得行/列:
> x[1,]
C1 C2 C3 C4 C5
1 3 5 7 9
> x[,3]
R1 R2
5 6
一些特殊情況
同向量一樣,越界會用NA填補,可以使用倒序等值序列蝉绷,等值序列冒號兩端必須要有數(shù)字:
> x[11]
[1] NA
> x[11:2]
[1] NA 10 9 8 7 6 5 4 3 2
如果雙下標(biāo)確定的二維坐標(biāo)實際不存在鸭廷,則報錯
> x[3,2]
Error in x[3, 2] : 下標(biāo)出界
4.數(shù)組
數(shù)組是可以在多維層次上存儲數(shù)據(jù)的對象∪勐穑可以認(rèn)為是多維的矩陣辆床。
array(data = NA, dim = length(data), dimnames = NULL)
數(shù)組的創(chuàng)建
使用array函數(shù)創(chuàng)建,data參數(shù)代表傳入的數(shù)據(jù)桅狠,dim表示維度讼载,dimnames為維度名稱宵晚。示例如下:
> dim1 <- c("A1","A2")
> dim2 <- c("B1","B2","B3")
> dim3 <- c("C1","C2","C3","C4")
> z <- array(1:24,c(2,3,4),dimnames = list(dim1,dim2,dim3))
> z
, , C1
B1 B2 B3
A1 1 3 5
A2 2 4 6
, , C2
B1 B2 B3
A1 7 9 11
A2 8 10 12
, , C3
B1 B2 B3
A1 13 15 17
A2 14 16 18
, , C4
B1 B2 B3
A1 19 21 23
A2 20 22 24
可以看出多維就是向量之間的組合,數(shù)值按行列填充维雇,而且維度的層次是由里到外:2,3晒他,4中2是行吱型,3是列,4是外部的行陨仅。這與使用NumPy數(shù)組創(chuàng)建的矩陣以及部分語言中的利用數(shù)組創(chuàng)建的矩陣都有差別津滞。
NumPy例子如下,可以看出有兩行灼伤,每行內(nèi)有三小行触徐,四列:
>import numpy
>numpy.empty((2,3,4))
array([[[ 3.10503618e+231, 1.29074048e-231, 2.20258734e-314,
2.20282008e-314],
[ 2.20475013e-314, 2.20276932e-314, 2.20247903e-314,
2.20272866e-314],
[ 2.20274681e-314, 2.20730875e-314, 2.20730883e-314,
2.20250846e-314]],
[[ 2.20853208e-314, 2.20279100e-314, 2.20260412e-314,
2.20320740e-314],
[ 2.20265303e-314, 2.20274598e-314, 2.20323984e-314,
2.20250954e-314],
[ 2.20296227e-314, 2.20301979e-314, 2.22325913e-314,
1.66880762e-308]]])
數(shù)組同矩陣一樣,也會循環(huán)補上缺失值:
> dim1 <- c("A1","A2")
> dim2 <- c("B1","B2","B3")
> dim3 <- c("C1","C2","C3","C4")
> z <- array(1:8,c(2,3,4),dimnames = list(dim1,dim2,dim3))
> z
, , C1
B1 B2 B3
A1 1 3 5
A2 2 4 6
, , C2
B1 B2 B3
A1 7 1 3
A2 8 2 4
, , C3
B1 B2 B3
A1 5 7 1
A2 6 8 2
, , C4
B1 B2 B3
A1 3 5 7
A2 4 6 8
獲取值的方式
下標(biāo)數(shù)等于維度數(shù)(使用第一個例子作為示范):
> z[1,2,3]
[1] 15
缺失不同的下標(biāo)可以獲得不同維度的組合:
> z[1,,]
C1 C2 C3 C4
B1 1 7 13 19
B2 3 9 15 21
B3 5 11 17 23
> z[1,2,]
C1 C2 C3 C4
3 9 15 21
> z[,2,]
C1 C2 C3 C4
A1 3 9 15 21
A2 4 10 16 22
> z[,,]
, , C1
B1 B2 B3
A1 1 3 5
A2 2 4 6
, , C2
B1 B2 B3
A1 7 9 11
A2 8 10 12
, , C3
B1 B2 B3
A1 13 15 17
A2 14 16 18
, , C4
B1 B2 B3
A1 19 21 23
A2 20 22 24
但是下標(biāo)數(shù)目不對會報錯:
> z[1,2]
Error in z[1, 2] : 量度數(shù)目不對
> z[1,,,]
Error in z[1, , , ] : 量度數(shù)目不對
> z[,,,]
Error in z[, , , ] : 量度數(shù)目不對
結(jié)合表達式或運算式:
> z[1,1:3,4]
B1 B2 B3
19 21 23
> z[1,c(1:3),4]
B1 B2 B3
19 21 23
5.數(shù)據(jù)框
數(shù)據(jù)框是表或者二維陣列狀結(jié)構(gòu)狐赡,也被稱作表撞鹉。其中每一列包含一個變量的值,并且每一行包含來自每一列的一組值颖侄。特點是列名非空鸟雏,行名唯一,每列數(shù)據(jù)項個數(shù)相同览祖。盡管每一列的模式必須唯一孝鹊,但是數(shù)據(jù)框可以將不同模式的列組合在一起。
data.frame(..., row.names = NULL, check.rows = FALSE, check.names = TRUE, fix.empty.names = TRUE, stringsAsFactors = default.stringsAsFactors())
數(shù)據(jù)框的創(chuàng)建
> studentID <- c(1,2,3,4)
> age <- c(16,17,18,19)
> country <- c("China","USA","Canada","Japan")
> status <- c("Handsome","Poor","Smart","Poor")
> sd <- data.frame(studentID,age,country,status)
> sd
studentID age country status
1 1 16 China Handsome
2 2 17 USA Poor
3 3 18 Canada Smart
4 4 19 Japan Poor
從這個簡單的例子可以看出來數(shù)據(jù)框可以認(rèn)為是含有相同個數(shù)數(shù)據(jù)項的向量的組合展蒂。check.rows與check.names等參數(shù)可以用來檢查不一致或重復(fù)又活,詳情可以查看R文檔。
獲取值的方式
單下標(biāo)獲取某一列:
> sd[3]
country
1 China
2 USA
3 Canada
4 Japan
雙下標(biāo)獲取單個數(shù)據(jù)項:
> sd[1,2]
[1] 16
單等值序列獲取多列:
> sd[1:3]
studentID age country
1 1 16 China
2 2 17 USA
3 3 18 Canada
4 4 19 Japan
雙等值序列獲取表的一部分:
> sd[1:3,2:4]
age country status
1 16 China Handsome
2 17 USA Poor
3 18 Canada Smart
取行/列/全部:
> sd[2,]
studentID age country status
2 2 17 USA Poor
> sd[,3]
[1] China USA Canada Japan
Levels: Canada China Japan USA
> sd[,]
studentID age country status
1 1 16 China Handsome
2 2 17 USA Poor
3 3 18 Canada Smart
4 4 19 Japan Poor
也可以使用 $ 取獲得某一列:
> sd$age
[1] 16 17 18 19
也可以結(jié)合c函數(shù):
> sd[c(1,2),c(3,4)]
country status
1 China Handsome
2 USA Poor
額外的問題1:
關(guān)于多下標(biāo)锰悼,有很多有趣的地方柳骄。這種表不是二維的嗎,多下標(biāo)取的是哪里的值呢松捉?以上面的數(shù)據(jù)框為例夹界,我們實踐一下:
1.前兩個下標(biāo)是坐標(biāo)
> sd[1,2,0]
age
1 16
> sd[1,2,1]
[1] 16
> sd[1,2,2]
[1] 16
> sd[1,2,3]
[1] 16
> sd[1,2,4]
[1] 16
> sd[1,2,5]
[1] 16
> sd[1,2,555]
[1] 16
> sd[1,2,-1]
[1] 16
> sd[1,2,-2]
[1] 16
前兩個下標(biāo)是坐標(biāo),第三個下標(biāo)取0時展示了該數(shù)值的行與列的位置隘世,取非0的值時并無作用可柿。
- 第一個和第三個數(shù)字是下標(biāo)
> sd[1,0,2]
data frame with 0 columns and 1 row
> sd[1,1,2]
[1] 1
顯然,R還是把前兩個當(dāng)成是二維坐標(biāo)丙者,最后的2并無作用复斥。
> sd[1,-1,2]
$age
[1] 16
$country
[1] China
Levels: Canada China Japan USA
$status
[1] Handsome
Levels: Handsome Poor Smart
然而,這個輸出十分有意思械媒。讓我們多實驗幾個數(shù)字目锭。
> sd[1,-1,1]
$age
[1] 16
$country
[1] China
Levels: Canada China Japan USA
$status
[1] Handsome
Levels: Handsome Poor Smart
> sd[1,-1,-1]
$age
[1] 16
$country
[1] China
Levels: Canada China Japan USA
$status
[1] Handsome
Levels: Handsome Poor Smart
> sd[2,-1,2]
$age
[1] 17
$country
[1] USA
Levels: Canada China Japan USA
$status
[1] Poor
Levels: Handsome Poor Smart
> sd[2,-2,3]
$studentID
[1] 2
$country
[1] USA
Levels: Canada China Japan USA
$status
[1] Poor
Levels: Handsome Poor Smart
> sd[-1,2,]
[1] 17 18 19
> sd[-1,3,4]
[1] USA Canada Japan
Levels: Canada China Japan USA
> sd[-2,-1,3]
age country status
1 16 China Handsome
3 18 Canada Smart
4 19 Japan Poor
> sd[-2,-2,3]
studentID country status
1 1 China Handsome
3 3 Canada Smart
4 4 Japan Poor
可以看出來第三個下標(biāo)完全沒有用评汰。。
第一個下標(biāo)為x(正)痢虹,第二個下標(biāo)為y(負)時被去,會展示出第x行除去第y列屬性的所有數(shù)值項。
第一個下標(biāo)為x(負)奖唯,第二個下標(biāo)為y(正)時惨缆,會展示出第y列除去第x行屬性的所有數(shù)值項。
第一個下標(biāo)為x(負)丰捷,第二個下標(biāo)為y(負)時坯墨,會展示出整個表除去第x行以及第y列屬性的所有數(shù)值項。
最后病往,四個下標(biāo)會報錯捣染。
> sd[,,,,]
Error in `[.data.frame`(sd, , , , , ) : 參數(shù)沒有用(, )
-
越界問題
僅當(dāng)單下標(biāo)越界時會報錯。雙下標(biāo)取值越界會返回NULL停巷,和前面的數(shù)據(jù)結(jié)構(gòu)返回NA不太一樣耍攘。
> sd[0]
data frame with 0 columns and 4 rows
> sd[7]
Error in `[.data.frame`(sd, 7) : undefined columns selected
> sd[1,6]
NULL
另外,前兩個下標(biāo)是負數(shù)且均絕對值越界時畔勤,返回的是整個表(數(shù)據(jù)框)少漆。
前兩個下標(biāo)是負數(shù)且前者絕對值越界時,返回的是表除去后者絕對值列數(shù)的所有數(shù)據(jù)值硼被。
前兩個下標(biāo)是負數(shù)且后者絕對值越界時示损,返回的是表除去前者絕對值行數(shù)的所有數(shù)據(jù)值。
> sd[-6,-1]
age country status
1 16 China Handsome
2 17 USA Poor
3 18 Canada Smart
4 19 Japan Poor
> sd[-5,-6]
studentID age country status
1 1 16 China Handsome
2 2 17 USA Poor
3 3 18 Canada Smart
4 4 19 Japan Poor
> sd[-2,-7]
studentID age country status
1 1 16 China Handsome
3 3 18 Canada Smart
4 4 19 Japan Poor
語言表達不太好嚷硫,大家可以自行理解检访。具體的原因等我參考R文檔后再補充。
額外的問題2:
- 綁定與解綁
一直使用 $ 得到一列屬性是一種簡單但不簡潔的做法仔掸,可以使用attach函數(shù)進行綁定操作脆贵。attach( ) 函數(shù)將數(shù)據(jù)框添加到R的搜索路徑中,R在遇到一個變量名后起暮,將檢查搜索路徑中的數(shù)據(jù)框卖氨。
> attach(sd)
The following objects are masked _by_ .GlobalEnv:
age, country, status, studentID
> summary(age)
Min. 1st Qu. Median Mean 3rd Qu. Max.
16.00 16.75 17.50 17.50 18.25 19.00
> plot(studentID,age)
> detach(sd)
在上面這個例子中,綁定了sd后负懦,summary函數(shù)使用的age就是特指sd中的age列筒捺。
detach( )將數(shù)據(jù)框從搜索路徑中移除,可以省略纸厉,但使用它是一種好的習(xí)慣系吭。(來也匆匆,去也沖沖)
- with函數(shù)
attach有兩個不太令人滿意的地方:假如環(huán)境中已經(jīng)有了一個名為age的對象颗品,原始對象會取得優(yōu)先權(quán)肯尺,綁定并沒有實際效果沃缘;多層的綁定/解綁會使結(jié)構(gòu)難以處理。
with函數(shù)中{ }結(jié)構(gòu)里所有的語句都只針對其中的數(shù)據(jù)框執(zhí)行则吟,無需擔(dān)心名稱沖突槐臀,賦值也同樣如此,在結(jié)構(gòu)體外不起作用氓仲,但是可以使用 <<-將對象保存在全局變量中峰档。
> with(sd,{
+ info1 <- summary(age)
+ info2 <<- summary(age)
+ info1
+ })
Min. 1st Qu. Median Mean 3rd Qu. Max.
16.00 16.75 17.50 17.50 18.25 19.00
> info1
錯誤: 找不到對象'info1'
> info2
Min. 1st Qu. Median Mean 3rd Qu. Max.
16.00 16.75 17.50 17.50 18.25 19.00
6.列表
列表包括不同類型的元素和對象,是他們的有序集合寨昙。
為什么要學(xué)會使用列表:
- 許多R語言函數(shù)默認(rèn)返回列表類型的對象。
- 列表允許使用一種簡單的方式組織和重新調(diào)試不想干的信息掀亩。
列表的創(chuàng)建:
由下面的例子可以看出列表就是不同成分見的有序組合舔哪。
> a <- c(1,2,3,4)
> b <- c("Type1","Type2","Type3")
> c <- matrix(1:10,nrow = 5)
> d <- "Come on boy"
> l <- list(a,b,c,d)
> l
[[1]]
[1] 1 2 3 4
[[2]]
[1] "Type1" "Type2" "Type3"
[[3]]
[,1] [,2]
[1,] 1 6
[2,] 2 7
[3,] 3 8
[4,] 4 9
[5,] 5 10
[[4]]
[1] "Come on boy"
可以指明不同成分的名稱,通過成分名訪問數(shù)據(jù)槽棍。如果成分名是數(shù)字捉蚤,需要加上引號,也就是說R認(rèn)為成分名必須是字符串炼七。
> a <- c(1,2,3,4)
> b <- c("Type1","Type2","Type3")
> c <- matrix(1:10,nrow = 5)
> d <- "Come on boy"
> l <- list(number = a,data =b,c,d)
> l
$number
[1] 1 2 3 4
$data
[1] "Type1" "Type2" "Type3"
[[3]]
[,1] [,2]
[1,] 1 6
[2,] 2 7
[3,] 3 8
[4,] 4 9
[5,] 5 10
[[4]]
[1] "Come on boy"
上面的例子中缆巧,number成分存在一個對象,在列表中編號是 1豌拙,data成分存在一個對象陕悬,在列表中編號是2,編號3按傅,4者無顯式成分名捉超。
個人認(rèn)為成分名盡量與數(shù)據(jù)對象一對一,不建議以下這種形式:
l <- list(age =a,data =c(b,c,d))
列表的其他創(chuàng)建函數(shù)可見R文檔唯绍。
獲取值的方式:
通過單下標(biāo)獲绕丛馈:
> l[1]
$number
[1] 1 2 3 4
> l[4]
[[1]]
[1] "Come on boy"
> l[]
$number
[1] 1 2 3 4
$data
[1] "Type1" "Type2" "Type3"
[[3]]
[,1] [,2]
[1,] 1 6
[2,] 2 7
[3,] 3 8
[4,] 4 9
[5,] 5 10
[[4]]
[1] "Come on boy"
結(jié)合表達式:
> l[1:3]
$number
[1] 1 2 3 4
$data
[1] "Type1" "Type2" "Type3"
[[3]]
[,1] [,2]
[1,] 1 6
[2,] 2 7
[3,] 3 8
[4,] 4 9
[5,] 5 10
> l[c(2,4)]
$data
[1] "Type1" "Type2" "Type3"
[[2]]
[1] "Come on boy"
通過成分名:
成分名作為下標(biāo)中需要加上引號。
> l[data]
Error in l[data] : 類別為'closure'的下標(biāo)不對
> l["data"]
$data
[1] "Type1" "Type2" "Type3"
> l$number
[1] 1 2 3 4
額外的問題:
除了0下標(biāo)外不存在的數(shù)值項會視為NA:
> l[0]
named list()
> l[7]
$<NA>
NULL
> l["HI"]
$<NA>
NULL
還有一些奇怪的東西大家可以來總結(jié)以下
> l[][2]
$data
[1] "Type1" "Type2" "Type3"
> l[][2][]
$data
[1] "Type1" "Type2" "Type3"
> l[][2][][1]
$data
[1] "Type1" "Type2" "Type3"
文中出現(xiàn)的部分函數(shù)說明
以下為R文檔簡述
- summary( ):summary is a generic function used to produce result summaries of the results of various model fitting functions. The function invokes particular methods which depend on the class of the first argument.
- str( ):Compactly display the internal structure of an R object, a diagnostic function and an alternative to summary (and to some extent). Ideally, only one line for each ‘basic’ structure is displayed. It is especially well suited to compactly display the (abbreviated) contents of (possibly nested) lists. The idea is to give reasonable output for any R object. It calls args for (non-primitive) function objects.
參考及引用資料
本人不會將以下資料用于商業(yè)用途并對其于自己的幫助表示由衷的感謝况芒。