第20章 高级编程
20.1 R语言回顾
20.1.1 数据类型
有两种最基本的据类型:原子向量(atomic vector)和泛型向量(generic vector)
#1 原子向量
原子向量是包含单个数据类型(逻辑类型、实数、复数、字符串或原始类型)的数组。
矩阵是一个具有维度属性(dim)的原子向量,包含两个元素(行和列)。
数组是一个具有dim属性的原子向量,其中包含三个或者更多元素。
attr()函数允许你创建任意属性并将其与对象关联,如dim() /dimnames() /names() /row,names() /class() /tsp(),最后一个用来创建时间序列对象。
需要注意的是:不能把不同的类型放到一个矩阵或者数组中。
#以矩阵为例
x <- c(1,2,3,4,5,6,7,8)
class(x)
dim(x)#为x加上dim属性
attr(x,"dim") <- c(2,4)
x
class(x)
dim(x)
attributes(x)#行和列名可以通过加上dimnames属性得到
attr(x,"dimnames") <- list(c("A1","A2"),
c("B1","B2","B3","B4"))
print(x)#通过去除dim属性来得到一维的向量
attr(x,"dim") <- NULL
x
class(x)
dim(x)
#2 泛型向量或列表
列表是原子向量和/或其它列表的集合。数据框是一种特殊的列表,集合中每个原子向量都有相同的长度。
head(iris)
attributes(iris)
unclass(iris)
以上数据框实际上是包括五个原子向量的列表,它有一个names属性(变量名的字符串向量),一个row.names属性(识别单个植物的数字向量)和一个带有data.frame的class属性。unclass()可以观察到每个向量代表数据框的一列的具体情况,此处没有截完整图。
#理解列表 以16章聚类分析技巧的数据为例
iris[1:4]
set.seed(1234)
fit <- kmeans(iris[1:4],3)
names(fit)
length(fit)
unclass(fit)
str(fit)
sapply(fit, class)
fit中包含的信息可以用以上代码了解到names提供成分名字,length展示对象包含多少成分,unclass直接检查对象的内容,str展示对象结构;sapply(fit, class)返回该类每个成分的对象。
#3 索引
提取对象中的元素公式:object [index],object是向量,index是一个整数向量或被命名的字符串向量。
提取成分中的元素公式:object [[integer]]
#没有命名的原子变量元素
x <- c(20,18,15,13)
x[3]x[c(1,4)]
#有命名的原子变量元素
x <- c(name="Lily",height=165,age=25)
x[c(1,3)]
x[c("name","age")]
#列表索引
fit <- kmeans(iris[1:4],3) #聚成3类
names(fit)
fit[c(1,3)]
fit[c(2:4)]
fit[2]
fit[[2]]#注意对比fit[2]返回的是列表,但fit[[2]]返回的是矩阵,如果想要把结果作为矩阵输入,那么应该使用双括号 [[ ]]
#获取单个的命名成分object [[integer]]与object$name等价
fit[[2]]
fit$centers
#将[]组合起来使用
fit[[2]]
fit[[2]][c(2,3),]#提取了fit的第二个成分并且返回第2和3行(第2和3类中四个变量的均值)
#画出K均值聚类分析的中心
set.seed(1234)
fit <- kmeans(iris[1:4],3)
means <- fit$centers
library(reshape2)
dfm <- melt(means)
names(dfm) <- c("cluster","measurement","centimeters")
dfm$cluster <- factor(dfm$cluster)
head(dfm)library(ggplot2)
ggplot(data = dfm,aes(measurement,centimeters,group=cluster))+
geom_point(size=3,aes(shape=cluster,color=cluster))+
geom_line(size=1,aes(color=cluster))+ggtitle("profile of iris cluster")
20.1.2 控制结构
三个控制流函数:for() if() ifelse()
for()函数语法:
for(var in seq){
statement
}
var是变量名,seq是计算向量的表达式,如果仅有一个语句,那么花括号可以省略
for(i in 1:4) print(1:i)
for(i in 3:7) print(1:i)
for(i in 5:1) print(2:i)
if()和else()函数语法
if(condition){
statement
}else {
statement
}
x<-c(1,3,5,7,8)
y<-c(20,23,37,48,59)
if(interactive()){
plot(x,y)
} else {
png("myplot.png")
plot(x,y)
dev.off()
}
#如果代码交互运行,interactive()函数返回TRUE,同时输出一个曲线图,
#否则,曲线被存在磁盘里
ifelse()函数语法:
ifelse(test,yes,no)
#检验p值并标记<0.05为显著
#通过向量循环完成
pvalues <- c(0.011,0.05,0.11)
results <- ifelse(pvalues<0.05,"significant","not significant")
print(results)#同样的结果可以用显示循环完成
pvalues <- c(0.011,0.05,0.11)
results1 <- vector(mode="character", length=length(pvalues))for(i in 1:length(pvalues)){
if (pvalues[i] < .05) results1[i] <- "Significant"
else results1[i] <- "Not Significant"
}
print(results1)#向量化版本更快~