实验1 R的基本知识-1

# 实验1 R的基本知识-1

# 1.输出无理数e的(近似)值;
exp(1)

# 2.求 1+2+…+100 的和;
sum(1:100)

# 3.求 1+1/2+…+1/15 的(近似)值;
sum(1/(1:15))

# 4.生成规则序列s1:1,1,1,2,2,2,…,6,6,6;
s1 = rep(1:6,each=3);s1

# 5.生成规则序列s2,使1,2,3,4各重复5,2,1,3次;
s2=rep(1:4,c(5,2,1,3));s2

# 将七名学生的成绩98,100,86,90,83,92,55赋值给向量Score,并完成9-14题:
Score=c(98,100,86,90,83,92,55);Score

# 6.选出Score中>=90的分量,求其均值;
mean(Score[Score>=90])
#mean(Score [which(Score>=90)]) which---选出逻辑值为True的.

# 7.将Score中<60的分量改写为60;
#S = Score;S[S<60]=60;S 不需要建立副本
Score[Score<60]=60;Score

# 8.显示Score中最低的三个成绩(按升序排列);
#S_sort = sort(Score);S_sort[1:3]
sort(Score)[1:3]

# 9.输出Score的排名次序(成绩最高者排第1),保存至Rank;
Rank = rank(-Score)  #rank---默认小的排第一

# 10.生成规则序列:st1708,…,st1714,保存至No;
num = 1708:1714;num
NO = paste("st",as.character(num),sep="");NO

# 11.将No,Score和Rank按列绑定并显示(提示:查询rbind及cbind命令的用法);
cbind(NO,Score,Rank)

实验2

# 1.用1~10与9~4,共16个数构造4阶方阵A,元素按行排列,然后完成题2-9:
A <- matrix(c(1:10,9:4), nrow = 4, ncol = 4,byrow = T);A #法一
#A <- t(array(c(1:10,9:4),dim = c(4,4))) #法二

# 2.将A转置,结果仍保留至A;
A <- t(A);A

# 3.显示A中由中间两行、两列构成的子块;
A[c(2,3),c(2,3)]
#A[c(-1,-4),c(-1,-4)]

# 4.计算A中各元素的平方和;
sum(A*A)

# 5.计算A各行的行均值;
rowMeans(A)
#apply(A, 1, mean)  #对行求均值

# 6.统计A的各列中大于5的元素个数;
colSums(A>5)

# 7.生成矩阵B,它由A去掉第3列得到;
B <- A[,-3]

# 8.计算矩阵乘积AB。
A %*% B

# 9.计算A的特征值、特征向量,结果保存至myList;
#myList <- list(V=eigen(A)$vectors,X=eigen(A)$values);myList #V表示特征向量,X表示特征值
myList <- eigen(A);myList

# 10.查看myList的基本信息
str(myList)

# 11.提取myList中特征值,按降序排列;
sort(myList$values,decreasing = T)

# 12.提取myList中标准化特征向量,计算其元素平方和(应该等于1);
#colSums(myList$V * myList$V)
colSums(myList$vectors^2)
#colSums(myList$vectors^2) & c(1,1,1,1)

# 13.给myList新增子对象test,其内容为"This is a test.";
myList$test <- "This is a test." ;myList

# 14.绑定myList,实现test的快捷访问,然后解除绑定;
attach(myList);test
detach(myList);test
# 15.删除myList中子对象test。
myList$test <- NULL ;myList

实验3

# 1.用屏幕交互输入命令读入全体元件寿命1600 1610...(从附表中拷贝),保存至tmp;
tmp <- scan()
1600  1610  1650  1680  1700  1700  1780 
1500  1640  1400  1700  1750 
1640  1550  1600  1620  1640  1600  1740  1800 
1510  1520  1530  1570  1640  1600

# 2.定义数据框lamp,使之包含元件寿命X(内容同tmp)与因子A(各元件所用材料,见附表)
#lamp <- data.frame(X=tmp,A=factor(c(rep(1,7),rep(2,5),rep(3,8),rep(4,6))));lamp
lamp <- data.frame(X = tmp,A = factor(rep(1:4,c(7,5,8,6))));lamp

# 3.显示lamp的前6行记录
head(lamp) #默认6行
#head(lamp,10)

# 4.查看lamp的简要信息(列/变量名、数据类型/构成等)
names(lamp)
str(lamp)

# 5.用命令返回lamp的行数、列数;
nrow(lamp)
ncol(lamp)

# 6.在新窗口中查看lamp,写出命令和界面操作过程
View(lamp)

# 7.计算lamp中元件寿命均值
mean(lamp$X)

# 8.查看lamp中因子A的水平
#lamp$A
levels(lamp$A)

# 9.在lamp中新增等级因子G,寿命区间(0,1600],(1600,1700]和(1700,Inf)分别对应二级、一级和特等;
#   统计各等级元件的频数表;
#G <- cut(tmp,breaks = c(0,1600,1700,Inf),labels=c("二级","一级","特等"));G
lamp$G = cut(tmp,breaks = c(0,1600,1700,Inf),labels=c("二级","一级","特等"));lamp

# 10.绑定lamp,以便快速访问其子对象(列)
attach(lamp);G  #注意在我们解绑lamp之前,均可快速访问其子对象
#detach(lamp);

# 11.统计元件材料与等级的交叉频数表;
table(A,G)

# 12.计算不同材料下元件寿命的均值
tapply(X,A,mean)

# 13.在lamp中新增厂家因子B,利用随机抽样,假定元件出自3个厂(1,2,3),各厂份额为55%,30%和15%
#    统计各等级元件的频数表;
#    思考:B能否可以像X,A一样快速访问?
lamp$B <- factor(   #为了和材料做区别,我们标记为"厂*"
  sample(c(1,2,3),26,replace = T,prob = c(0.55,0.30,0.15)),
  levels=c(1,2,3),
  labels = c("厂1","厂2","厂3")
);
lamp

table(G)
#不能和X,A一样快速访问,B是在绑定之后建立的

# 14.解除对lamp绑定;
detach(lamp);

# 15.从工作空间中清除变量tmp;
rm(tmp)

实验4 成绩数据分析

#######################################################
#实验4 成绩数据分析(2020/05/20) 
#######################################################

#============================================================
#输入数据
#============================================================
#1.设置工作路径
#  读入学生成绩score131-2.txt,保存成S
#  读入学生信息student132.txt,保存成Stu
#  指定各门课程学分:2,5,0.5,5,1,1,2,3,3,1,0.5,保存成向量xf
setwd("F:/R_file/R语言与数据挖掘/实验4 成绩数据分析")
S <- read.table(file ="score131-2.txt" ,header = T);S
Stu <- read.table(file ="student132.txt" ,header = T);Stu
xf <- c(2,5,0.5,5,1,1,2,3,3,1,0.5);xf

#============================================================
#数据的处理
#============================================================
#2.计算每名学生平均成绩,保留1位小数(round命令),保存至S中的Mean列
S$Mean_S <- round(rowMeans(S[3:13]),digits = 1)

#3.计算每名学生不及格门数,保存至S中的No.fail列
########################################################
#  提示:用逻辑表达式判断科目及格与否,再对逻辑值求行和得到不及格门数
########################################################
S$No.fail <- rowSums(S[3:13] < 60)

#4.计算每名学生获得学分(不及格科目不计入),保存至S中的xf列
########################################################
#  提示:用逻辑表达式判断科目及格与否,再用向量、矩阵乘法计算所得学分
########################################################
S$xf <- (S[3:13] >= 60) %*% xf  #注意已经增加了两列

#5.计算每名学生的平均学分绩点(GPA),保留2位小数,保存至S中的GPA列
########################################################
#GPA(0~5分制)的计算:sum(各科绩点*对应学分)/应获得的总学分
#各科绩点的计算:60以下0,60计1.0,60以上每增加1分计0.1
#提示:由原始成绩计算对应绩点矩阵,再用矩阵乘法。在已有代码后补充完成
########################################################
tmp <- as.matrix(S[,3:13])      #提取成绩转为矩阵格式
jd <- ifelse(tmp<60, 0, 1+(tmp-60)*0.1)  #计算绩点矩阵
S$GPA <- round((jd %*% xf)/sum(xf),digits = 2)

#6.计算学生在专业内、班级内的GPA排名(从高到低),分别保存至S中的Rank、Rank1列
########################################################
#提示:班内排名是筛选子集后的排名
########################################################
S$Rank <- rank(-S$GPA)
S$Rank1 <- c(rank(-S[S$Class=="132班",]$GPA),rank(-S[S$Class=="131班",]$GPA))

#7.以GPA值0,2.0,3.0,3.5,5为界将学生划分差/中/良/优,生成因子保存至S中Grade列
#  将处理后的数据写入文件result.txt
S$Grade <- cut(S$GPA,breaks = c(0,2.0,3.0,3.5,5),labels = c("差",'中','良','优'))
write.table(S, file="result.txt", 
            sep=" ", quote = FALSE, append = FALSE, na = "NA")

#============================================================
#成绩分析——两班成绩对照
#============================================================
#8.计算两班GPA平均分
tapply(S$GPA, S$Class, mean)

#9.计算两班各科平均分
colMeans(S[S$Class=="132班",3:13])
colMeans(S[S$Class=="131班",3:13])

#10.作等级的频数统计
#   作班级、等级的交叉频数统计
table(S$Class,S$Grade)

#============================================================
#成绩分析——132班班内成绩分析
#============================================================
#11.按学号合并S与Stu两表,保存至S_Merge
S_Merge <- merge(S,Stu,by="No",all = F)

#12.将S_Merge各行按GPA列降序(从大到小)排序,结果仍存至S_Merge 
S_Merge <-S_Merge[order(S_Merge$GPA,decreasing = T),]

#13.作132班性别、等级的交叉频数统计
attach(S_Merge)
table(Sex,Grade)
#   作132班班委/非班委、等级的交叉频数统计
table(Type,Grade)
#   作132班宿舍、等级的交叉频数统计
table(Room,Grade)

#14.筛选并输出132班GPA低于2.0的学生学号
S_Merge[GPA < 2.0,]$No
detach(S_Merge)

实验5 分支、循环与函数

#######################################################
#实验5 分支、循环与函数
#######################################################

#1.要求:编写函数myFun,输入参数为x(数值向量),返回值为x中分量x_1,...,x_n
# (n为分量个数)的一种特殊幂和:x_1^k+...+x_n^k,其中若x_i为偶数,
#  则k取2,若x_i为奇数,则k取-1。最后以向量1,2,…,5调用函数进行测试。
# 思考:不编写函数,怎样实现上述功能?
myFun1 <- function(x){
  return (sum(x[(x %% 2) == 0]^2) + sum(x[(x %% 2) == 1]^(-1)))
  
}

myFun2 <- function(x){
  s <- 0
  for(i in 1:length(x)){
    if(x[i]%%2==0)	s <- s + x[i]^2
    if(x[i]%%2==1)	s <- s + x[i]^(-1)
    #或写作 s <- s + ifelse(x[i]%%2==0, x[i]^2, x[i]^(-1))
  }
  return(s)
}	

x <- 1:5
myFun1(x)
myFun2(x)

#不写函数
res <- sum(x[(x %% 2) == 0]^2) + sum(x[(x %% 2) == 1]^(-1))

#2.背景:(数论中的"3n+1"问题)对于任意大于1的自然数n,若n为奇数,则将n变为3n+1,
#  否则变为n的一半。经过若干次这样的变换,一定会使n变为1。例如3->10->5->16->8->4->2->1。
#  要求:用两种方法(递归、非递归)编写函数test,输入正整数n,输出变换为1所需的次数。
#  最后用3做测试(答案为7)。

#非递归
test1 <- function(n){ 
  num <- 0
  while (n != 1){
    if (n %% 2 ==1){
      n <- 3*n+1
      num = num+1
    }else{
      num = num+1
      n <- n/2
  }
  }
  return(num)
} 
 
test1(3)
 
#递归
test2 <- function(n){
  if (n==1) return(0)
  if (n%%2 ==1) return(1+(test2(3*n+1))) 
  else return(1+(test2(n/2)))
}

test2(3)