繼續(xù)深入學(xué)習(xí)R語(yǔ)言曹阔,爭(zhēng)取對(duì)其比較熟悉
函數(shù)
#R語(yǔ)言編程的核心就是函數(shù)
#count the number of odd integers in x
oddcount <- function(x){
k <- 0
for(n in x){
if(n%%2==1) k <- k + 1
}
print(paste("the odd number is:",k,sep = ""))
return(k)
}
x <- c(1,2,4,2,5)
oddcount(x)
#R語(yǔ)言盡可能避免使用循環(huán)炼吴,如果要寫(xiě),也要簡(jiǎn)潔
#慎重使用沒(méi)有顯示調(diào)用的return()
#使用超賦值運(yùn)算符 <<- 在函數(shù)內(nèi)部給全局變量賦值```
#矩陣
也可以稱作是向量,矩陣還有兩個(gè)附加的屬性篮洁,行數(shù)和列數(shù)
m <- rbind(c(1,2),c(3,4))
使用rbind將兩個(gè)向量結(jié)合成一個(gè)矩陣
矩陣乘法運(yùn)算,%*%
m%*%m
從矩陣中提取出子矩陣
m[1,]
m[,2]```
list列表
#其中內(nèi)容的各項(xiàng)可以屬于不同的數(shù)據(jù)類(lèi)型
x <- list(u=c(2,3),v="abc")
x$u
x$v
#x[1]表示獲取第一個(gè)組件殃姓,x[[1]]表示獲取第一個(gè)組件里面的值(向量)
#但是x[[2]]表示獲取第二個(gè)組件里面的值
x[[1]]
#要獲取具體的值袁波,這樣操作
x[[1]][2]
#列表的一種常見(jiàn)用法是把多個(gè)值打包組合到一起,然后從函數(shù)返回
hn <- hist(Nile)
hn
#另外一種比較簡(jiǎn)潔的打印方式
#str表示structure蜗侈,這個(gè)函數(shù)可以顯示任何R對(duì)象的內(nèi)部結(jié)構(gòu)
str(hn)```
#數(shù)據(jù)框
其實(shí)是列表篷牌,只不過(guò)列表中的每個(gè)組件是由前面提到的矩陣數(shù)據(jù)的一列構(gòu)成的向量
所以data.frame構(gòu)造函數(shù)傳入的是列表,當(dāng)然如果傳單個(gè)向量也可以踏幻,不過(guò)就是沒(méi)有名字吧
如果需要名字枷颊,那么就要指定向量的名字
d <- data.frame(list(kids=c("jack","kevin"),ages=c(21,22)))
d1 <- data.frame(numbers=c(1,2),desc=c("ac","ab"))
str(d)
d
通常數(shù)據(jù)框是通過(guò)讀取文件或者數(shù)據(jù)框來(lái)創(chuàng)建的```
類(lèi)
#S3類(lèi),實(shí)例僅僅是列表该面,但是有個(gè)屬性:類(lèi)名
#hist輸出的還有一個(gè)屬性夭苗,用來(lái)指定列表的類(lèi),即histogram類(lèi)
#然后指定類(lèi)是為了使用泛型函數(shù)吆倦,泛型函數(shù)代表一個(gè)函數(shù)族听诸,每個(gè)函數(shù)有相似的功能,
#但是適用于某個(gè)特定的類(lèi)蚕泽,所以列表有這個(gè)屬性晌梨,就可以作為區(qū)分桥嗤,如plot()函數(shù)就是一個(gè)函數(shù)族```
#向量
循環(huán)補(bǔ)齊,篩選仔蝌,向量化(對(duì)向量的每一個(gè)元素應(yīng)用函數(shù))
適用typeof()來(lái)查看數(shù)據(jù)類(lèi)型
x <- c(1,2,3,4)
typeof(x)
要想添加或者刪除元素泛领,則重新給向量賦值
x <- c(x[1:2],5,x[3:4])
x
獲取向量長(zhǎng)度
length(x)
要使用向量中特定的元素,必須首先去聲明敛惊,而不能直接y[1] <- 2這樣渊鞋,必須像下面這樣
y <- vector(length=2)
y[1] <- 2
y[3] <- 4
y
或者這樣
y <- c(2,4)
使用c()創(chuàng)建了一個(gè)新向量,然后綁定給變量y
函數(shù)式語(yǔ)言中瞧挤,讀寫(xiě)向量中的元素锡宋,由函數(shù)來(lái)完成,R如果并不知道y是一個(gè)向量
那么函數(shù)就沒(méi)有執(zhí)行的對(duì)象```
循環(huán)補(bǔ)齊
c(1,2,3) + c(4,2,6,3)
x <- rbind(c(1,2),c(2,4))
x + c(1,2)```
#向量的運(yùn)算
+也是函數(shù)特恬,"+"(),使用雙引號(hào)是因?yàn)?是特殊字符
2+3
"+"(2,3)
*函數(shù)使用方式是元素與元素相乘```
向量索引
#選擇給定向量中特定索引的元素構(gòu)成子向量
#向量1[向量2]执俩,返回向量1中索引為向量2的元素
y <- c(1,2,4,5,2)
y[c(1,4)]
#負(fù)數(shù)下表表示把相應(yīng)的元素剔除
y[-2]
#去除最后一個(gè)元素
y[1:length(y)-1]
y[-length(y)]```
#使用:運(yùn)算符創(chuàng)建向量
5:8
和python切片中冒號(hào)不一樣的是,這里既包含前面也包含后面元素
另外冒號(hào)運(yùn)算符優(yōu)先級(jí)高于-號(hào)
1:5-1
1:(5-1)```
seq()函數(shù)創(chuàng)建向量癌刽,等差序列
seq(1,5,2)
#然后可以使用下面的功能
x <- c(5,23,41,42)
seq(x)
#就是seq()會(huì)建立一個(gè)x向量的等差索引役首,并且如果x為空的時(shí)候,會(huì)正確的計(jì)算空值NULL
for(i in seq(x)){
print(i)
print(x[i])
}```
#rep()函數(shù)可以將同一個(gè)常數(shù)放在長(zhǎng)向量中
x <- rep(8,4)
將8重復(fù)4次显拜,創(chuàng)建一個(gè)向量
x <- rep(c(1,2,3),3)
each參數(shù)衡奥,指定前面要重復(fù)的東西重復(fù)次數(shù)
x <- rep(c(1,2),each=2)
1 1 2 2```
使用all()和any()
#報(bào)告參數(shù)是否至少有一個(gè)或者全部為T(mén)RUE
x <- 1:10
all(x>8)
any(x>9)
#也就是首先形成一個(gè)布爾向量为牍,然后進(jìn)行判斷
#篩選也是如此瓷胧,形成布爾向量,然后只索引為T(mén)RUE的索引值```
#向量化
對(duì)向量x中的每一個(gè)元素使用函數(shù)f()
提高R代碼執(zhí)行速度的有效方法之一就是向量化氯质,將應(yīng)用到向量的函數(shù)實(shí)際應(yīng)用在每一個(gè)元素上
一些向量化運(yùn)算矮台,+ * >
如果一個(gè)函數(shù)使用了向量化的運(yùn)算符乏屯,那么它也被向量化了
一些函數(shù),sort(),round()都是向量化的
f <- function(x,c){
return((x+c)^2)
}
傳入的參數(shù)瘦赫,c作為標(biāo)量辰晕,x為向量就會(huì)產(chǎn)生循環(huán)補(bǔ)齊進(jìn)行運(yùn)算
當(dāng)然也可以傳入c為向量,如果要限制為標(biāo)量确虱,那么要進(jìn)行判斷
f <- function(x,c){
if(length(c)!=1){
stop("vector c not allowed")
}
return((x+c)^2)
}```
向量輸入與輸出
#有的函數(shù)直接返回向量
z12 <- function(z){
return(c(z,z^2))
}
x <- 1:8
z12(x)
matrix(z12(x),ncol=2)
#在sapply諸如此類(lèi)的函數(shù)里含友,調(diào)用函數(shù)不需要帶括號(hào)
#sapply會(huì)直接輸出矩陣
sapply(x,z12)```
#NA表示缺失值,NULL表示不存在的值
x <- c(88,NA,12,168,13)
y <- c(x[-2],NULL)
mean(x)
mean(y)
mean(x,na.rm = T)
R會(huì)自動(dòng)跳過(guò)空值NULL,但是不會(huì)跳過(guò)NA
NULL一個(gè)用法是在循環(huán)中創(chuàng)建向量校辩,其中每次迭代在向量上增加一個(gè)元素
z <- NULL
for(i in 1:10){
z <- c(z,i)
}
NULL被作為不存在而計(jì)數(shù)窘问,也就是相當(dāng)于沒(méi)有```
篩選
#R語(yǔ)言函數(shù)式特性的另外一個(gè)特征
z <- c(5,2,-3,1)
z[z*z > 4]
#首先獲取一個(gè)布爾值向量,然后用得到的布爾值向量篩選出z中所需要的元素
z[z>3] <- 0```
#使用subset()進(jìn)行篩選
它與普通方法區(qū)別在于處理NA值上
x <- c(6,1:3,NA,12)
x[x>5]
subset默認(rèn)忽略NA
subset(x,x>5)```
which函數(shù)
#前面篩選都是獲得篩選后的值惠赫,但是which函數(shù)將獲取到滿足條件的索引值
which(z*z>4)
#which報(bào)告在z*z>4運(yùn)行后,哪些值是TRUE故黑,返回其索引
#它有個(gè)用法非常方便就是在向量中找出滿足一定條件元素首次出現(xiàn)的位置
first1a <- function(x){
return(which(x==1)[1])
}
x <- c(3,2,1,4,1,4,5)
print(first1a(x))```
#向量化的ifelse()函數(shù)
除了正常用法ifelse(b,u,v),b為真儿咱,返回u,否則返回v
向量化用法是b[i]為真庭砍,返回u[i],否則返回v[i],最終返回一個(gè)向量
x <- 1:10
ifelse(x>5,TRUE,FALSE)```
判斷向量是否相等
#==不能使用,因?yàn)?=是向量化的混埠,比較的是向量中每個(gè)元素是否相等
x <- 1:3
y <- c(1,3,4)
x == y
#當(dāng)然可以這樣做
all(x == y)
#也可以簡(jiǎn)單的使用identical函數(shù)
identical(x,y)
#判斷對(duì)象是否完全一樣
z <- c(1,2,3)
#identical不一樣的原因是c()產(chǎn)生的是浮點(diǎn)數(shù)怠缸,而1:3產(chǎn)生的是整數(shù),但是==可以正常钳宪,因?yàn)楫吘怪凳且粯拥?identical(x,z)
all(x == z)```
#使用names()函數(shù)給向量命名
x <- c(1,2,3)
names(x) <- c("i","love","you")
使用names索引元素
x["i"]
移除名字
names(x) <- NULL```
c()
#傳遞到c()參數(shù)有不同類(lèi)型揭北,則會(huì)被降級(jí)到同一個(gè)類(lèi)型,該類(lèi)型最大程度的保留他們的共同特性
c(5,1,"iloveyou")
#全成字符串了
#另外c()對(duì)數(shù)據(jù)有扁平化效果吏颖,和Python不一樣
c(1,2,4,c(2,4,4))```