380 likes | 397 Views
R 程式流程控制. 結構化程式設計 三種結構 : 循序 sequential 、選擇 selection 、重複 iteration 各種程式範例說明. 程式流程控制 (branch). type I : if (logical condition TRUE) {statements1} type II : if (logical condition TRUE ) {statements 1} else {statements 2}
E N D
R程式流程控制 結構化程式設計三種結構: 循序sequential、選擇selection、重複iteration 各種程式範例說明
程式流程控制(branch) • type I : if (logical condition TRUE) {statements1} • type II : if (logical condition TRUE ) {statements 1} else {statements 2} • type III : if (logical condition1 TRUE) {statements 1} else if (logical condition2 TRUE) {statements 2} else {statements 3}
程式流程控制(loop) • for (計數變數 in 範圍) {statements} • while ((logical condition TRUE)) {statements} • repeat { statements if (logical condition TRUE) break statements } • break跳離整個迴圈 next:跳過這一回合的迴圈
範例1: 計算BMI height=rnorm(30,160,15) weight=rnorm(30,60,10) bmi=round(weight/(height/100)^2,2) n=length(height) comment=character(n) #one branch for (i in 1:n) { if (bmi[i]>=18 && bmi[i]<=23) comment[i]="good" } data=data.frame(height,weight,bmi,comment) data
範例1: 計算BMI #two branches for (i in 1:n) { if (bmi[i]>=18 && bmi[i]<=23) comment[i]="good" else comment[i]="bad" } data=data.frame(height,weight,bmi,comment) data
範例1: 計算BMI #three branches count1=0;count2=0;count3=0 for (i in 1:n) { if (bmi[i]>23) {comment[i]="fat" count1=count1+1} else if (bmi[i]>=18) {comment[i]="good" count2=count2+1} else {comment[i]="thin" count3=count3+1} } cat("good people=",count2,"\n") cat("fat people=",count1,"\n") cat("thin people=",count3,"\n")
範例1: 計算BMI #取10次bmi的平均 mv=NULL for (j in 1:10) { height=rnorm(30,160,15) weight=rnorm(30,60,10) bmi=round(weight/(height/100)^2,2) n=length(height) comment=character(n) for (i in 1:n) {……} mv=c(mv,mean(bmi)) } mv mean(mv)
範例2: 條件式的寫法 #判斷閏年 year=2016 if (year %%4==0 && year %%100 !=0 || year %%400==0) cat(year," is LEAP\n") else cat(year," is NOT LEAP\n")
範例2: 條件式的寫法 #判斷是否為三角形 a=6 b=10 c=8 if (a+b>c && b+c>a && c+a>b) cat(" is Triangle\n") else cat(“NOT Triangle\n")
範例2: 條件式的寫法 #判斷是否為直角三角形 a=6 b=10 c=8 if (a^2+b^2==c^2 || b^2+c^2==a^2 || c^2+a^2==b^2) cat(" is right angle Triangle\n")
範例3: 迴圈程式流程一 # 1+2+3+...+10= m=10 sum=0 for (i in 1:m) sum=sum+i cat("SUM=",sum,"\n") #factorial n=6 fact=1 for (i in 1:n) fact=fact*i cat("Factorial 6=",fact,"\n")
範例3: 迴圈程式流程一 # sqrt while n=20 l=0 h=n while(h-l>0.0001) { m=(l+h)/2 if (m*m<=n) l=m else h=m } cat("Sqrt 20=",m,"\n")
範例4: 迴圈程式流程二 # 1+3+5+...+10= m=10 sum=0 for (i in seq(1,m,by=2)) { sum=sum+i } cat("SUM=",sum,"\n")
範例4: 迴圈程式流程二 # 1+3+5+...+10= m=10 sum=0 for (i in 1:m) { if (i %%2 ==0) next else sum=sum+i } cat("SUM=",sum,"\n")
範例4: 迴圈程式流程二 # 1+3+5+...+10= m=10 sum=0 i=1 while (i<=m) { sum=sum+i i=i+2 } cat("SUM=",sum,"\n")
範例5: 迴圈程式流程三 # 3 digits Armstrong Number for (i in 1:9) for (j in 0:9) for (k in 0:9) { num1=100*i+10*j+k num2=i^3+j^3+k^3 if (num1==num2) cat(num1,"\t") }
範例5: 迴圈程式流程三 # 50-100 Prime for (i in 50:100) { prime=TRUE n=round(i/2,0) for (j in 2:n) { if (i%%j==0) {prime=FALSE break } } if (prime) {cat(i," ")} }
範例6: brain分組次數和頂高標 brain=read.csv("d:\\stella\\R\\brain.csv", header=T) attach(brain) Gender2=c("Male","Female")[Gender+1] index=1+(BrainSize>mean(BrainSize)) BrainSize2=c("Small","Big")[index] index2=1+(Weight>mean(Weight)) Weight2=c("Thin","Fat")[index2] (table3D=table(Gender2,Weight2,BrainSize2)) (ftable(data.frame(Gender2,Weight2,BrainSize2)))
範例6: brain分組次數和頂高標 #FSIQ m:high standard and h:top standard summary(brain) bm=brain[brain$FSIQ>mean(brain$FSIQ),] (m=mean(bm$FSIQ)) bh=brain[brain$FSIQ>quantile(brain$FSIQ,0.75),] (h=mean(bh$FSIQ))
範例6: brain分組次數和頂高標 # 3 IQ m: high standard h:top standard mv=NULL;hv=NULL for (i in 2:4) {bm=brain[brain[,i]>mean(brain[,i]),] m=mean(bm[,i]) mv=c(mv,m) bh=brain[brain[,i]>quantile(brain[,i],0.75),] h=mean(bh[,i]) hv=c(hv,h)} cat("\tFSIQ\t VIQ\t PIQ\n") mv;hv
範例7:以平均數取代NA test=read.csv("d:/stella/R/test.csv") for (j in 2:4) { m=mean(test[,j],na.rm=TRUE) for (i in 1:nrow(test)) if (is.na(test[i,j])) test[i,j]=m } write.csv(test,"d:/stella/R/test1.csv“ ,row.names=F)
範例8:計算不為NA的筆數 test=read.table("d:/R/data/txt/cancers.txt") cnt=rep(0,5) for (i in 2:nrow(test)) { for (j in 1:ncol(test)) { if (!(is.na(test[i,j]))) cnt[j]=cnt[j]+1 } } write(cnt,file="d:/R/data/txt/can.txt")
範例9:水平和垂直合併 #vertical merge input=read.table("D:\\stella\\R\\input1.txt",header=T) input1=read.table("D:\\stella\\R\\input2.txt",header=T) vall=rbind(input,input1) vall
範例9:水平和垂直合併 #horizontal merge test=read.table("D:\\stella\\R\\input3.txt", header=T) t0=test[,1:4] t1=test[grep("tea",test$item1,ignore.case=FALSE),c(1,5)] t2=test[grep("tea",test$item2,ignore.case=FALSE),c(1,6)] tt=merge(t1,t2,by="id",all=T) hall=merge(t0,tt,by="id",all.tt=T) hall
範例9:水平和垂直合併(union) #method 2 : horizontal merge test=read.table("D:\\stella\\R\\input3.txt", header=T) l1=grep("tea",test[,5]) l2=grep("tea",test[,6]) t=test[union(l1,l2) ,] t[order(t$id),] # method 2 :vertical merge input=read.table("D:\\stella\\R\\input1.txt",header=T) input1=read.table("D:\\stella\\R\\input2.txt",header=T) (vall=rbind(input,input1)) dup=union(input$id,input1$id) (vall[dup, ])
範例10:迴圈執行繪圖 # method 1:all files of one directory (dir=list.files("d:/stella/R/baby",full.name=TRUE)) # infile=dir[grep(“.txt”,dir)] par(mai=c(0.5,0.5,0.5,0.5),mfrow=c(3,4)) lbl=c("~20","20~25","25~30","30~35","35~40","40~") for (i in 1:length(dir)) { file0=dir[i]; data=read.table(file=file0,header=T) hist(data$bwt,main=paste("babies weight hist age=",lbl[i])) plot(data$height,data$weight,main=paste("height and weight plot age=",lbl[i])) }
範例10:迴圈執行繪圖 baby1.txt-baby6.txt對應先前用 subset函數輸出的檔grp1-grp6
範例10:迴圈執行繪圖 #method 2:seqential file names利用循序檔名 pdf("d:\\stella\\R\\baby\\babies.pdf") # ,family=“GB1” par(mai=c(0.5,0.5,0.5,0.5),mfrow=c(3,2)) lbl=c("~20","20~25","25~30","30~35","35~40","40~") for (i in 1:6) { fn=paste("d:\\stella\\R\\baby\\baby",i,".txt",sep=""); data=read.table(file=fn,header=T) hist(data$bwt,main=paste("babies weight hist age=",lbl[i])) plot(data$height,data$weight,main=paste("height and weight plot age=",lbl[i])) } graphics.off() # or dev.off()