版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡介
1、方法2、應(yīng)用實(shí)例3、實(shí)驗(yàn)作業(yè)實(shí)驗(yàn)內(nèi)容學(xué)習(xí)R語言中程序設(shè)計(jì)方法實(shí)驗(yàn)?zāi)康牡谒闹v-程序設(shè)計(jì)程序控制結(jié)構(gòu)R是一個(gè)表達(dá)式語言(expressionlanguage),其任何一個(gè)語句都可以看成是一個(gè)表達(dá)式。表達(dá)式之間以分號(hào)分隔或用換行分隔。表達(dá)式可以續(xù)行,只要前一行不是完整表達(dá)式(比如末尾是加減乘除等運(yùn)算符,或有未配對的括號(hào))則下一行為上一行的繼續(xù)。若干個(gè)表達(dá)式可以放在一起組成一個(gè)復(fù)合表達(dá)式,作為一個(gè)表達(dá)式使用。組合用大括號(hào)表示,如:>{+x<-15;+x;}
[1]15R語言也提供了其它高級(jí)程序語言共有的分支、循環(huán)等程序控制結(jié)構(gòu)。第四講-程序設(shè)計(jì)分支結(jié)構(gòu)(if/else、switch語言)
if/else語句分支結(jié)構(gòu)包括if結(jié)構(gòu):
if(條件)表達(dá)式1或
if(條件)表達(dá)式1else表達(dá)式2其中的“條件”為一個(gè)標(biāo)量的真或假值,表達(dá)式可以是用大括號(hào)包圍的復(fù)合表達(dá)式。有else子句時(shí)一般寫成:
if(條件){表達(dá)式組……}else{表達(dá)式組………}
這樣的寫法可以使else不至于脫離前面的if。第四講-程序設(shè)計(jì)例如,如果變量lambda為缺失值就給它賦一個(gè)缺省值,可用:>if(is.na(lambda))lambda<-0.5;
又比如要計(jì)算向量x的重對數(shù),這只有在元素都為正且對數(shù)都為正時(shí)才能做到,因此需要先檢查:>if(all(x>0)&&all(log(x))>0){y<-log(log(x));print(cbind(x,y));}else{cat('Unabletocomply\n');}
注意“&&”表示“與”,它是一個(gè)短路運(yùn)算符,即第一個(gè)條件為假時(shí)就不計(jì)算第二個(gè)條件。如果不這樣此例中計(jì)算對數(shù)就可以有無效值。在條件中也可以用“||”(兩個(gè)連續(xù)的豎線符號(hào))表示“或”,它也是短路運(yùn)算符,當(dāng)?shù)谝粋€(gè)條件為真時(shí)就不再計(jì)算第二個(gè)條件。第四講-程序設(shè)計(jì)在用R編程序時(shí)一定要時(shí)刻牢記R是一個(gè)向量語言,幾乎所有操作都是對向量進(jìn)行的。而R中的if語句卻是一個(gè)少見的例外,它的判斷條件是標(biāo)量的真值或假值。比如,我們要定義一個(gè)分段函數(shù)f(x),當(dāng)x為正時(shí)返回1,否則返回0,馬上可以想到用if語句實(shí)現(xiàn)如下:
>if(x>0)1else0當(dāng)x是標(biāo)量時(shí)這個(gè)定義是有效的,但是當(dāng)自變量x是一個(gè)向量時(shí),比較的結(jié)果也是一個(gè)向量,這時(shí)條件無法使用。所以,這個(gè)分段函數(shù)應(yīng)該這樣編程:
>y=numeric(length(x))>y[x>0]<-1>y[x<=0]<-0
#這句可以省略第四講-程序設(shè)計(jì)對于條件語句是向量形式,R提供了ifelse()函數(shù),它的使用格式為
>ifelse(condition,a,b)它表示,當(dāng)condition[i]成立的時(shí)候,對應(yīng)的取值為a[i],否則取值為b[i]。最終返回一個(gè)和參數(shù)向量同長的向量>x<-c(55,60,85,90);>a<-"pass";b<-"fail">ifelse(x>=60,a,b)[1]"fail""pass""pass""pass">a<-c("a1","a2","a3","a4")>b<-c("b1","b2","b3","b4")>ifelse(x>=60,a,b)[1]"b1""a2""a3""a4"若a,b和x不是等長的,則較短的循環(huán)使用第四講-程序設(shè)計(jì)有多個(gè)if語句時(shí)else與最近的一個(gè)配對。可以使用if...elseif...elseif...else...的多重判斷結(jié)構(gòu)表示多分支。多分支也可以使用switch()函數(shù)。>x=0;>if(x>0){value<-x}elseif(x<0){value<--x}elseif(x==0){value="ZERO"}>value[1]''ZERO"第四講-程序設(shè)計(jì)switch語句switch是多分支語句,其用法為:
>switch(statement,list);statement是一個(gè)表達(dá)式,list是列表,也可以用有名定義。根據(jù)表達(dá)式與list的關(guān)系返回一個(gè)值。如果表達(dá)式返回值屬于1:length(list)中的一個(gè),則返回list中相應(yīng)位置的值,否則返回NULL。
>a<-switch(1,2+2,mean(1:10),rnorm(4));a[1]4
>a<-switch(2,2+2,mean(1:10),rnorm(4));a[1]5.5>x<-3>a<-switch(x,2+2,mean(1:10),rnorm(4));a[1]0.32029210.3057707-0.49221250.1280950>a<-switch(4,2+2,mean(1:10),rnorm(4));a[1]NULL第四講-程序設(shè)計(jì)當(dāng)list是有名定義時(shí),statement等于變量名時(shí),返回該變量名所對應(yīng)的值,否則返回NULL
>x<-"fruit";
>a<-switch(x,fruit="apple",drink="coffee",vegetable="broccoli");a[1]"apple"
>x<-"meat";
>a<-switch(x,fruit="apple",drink="coffee",vegetable="broccoli");a[1]NULL第四講-程序設(shè)計(jì)循環(huán)結(jié)構(gòu)(for/while/repeat)
for語句
循環(huán)結(jié)構(gòu)中常用的是for循環(huán),是對一個(gè)向量或列表的逐次處理,格式為for(nameinvalues){expression}如:求1到100的和>sum<-0;for(iin1:100){sum<-sum+i;i<-i+1}
sum;[1]5050
第四講-程序設(shè)計(jì)當(dāng)然,如果只是要求各元素的和,只要調(diào)用sum(x)即可。所以,編寫程序要精簡,應(yīng)盡量避免使用顯式循環(huán)。我們再舉一個(gè)例子。比如,我們要計(jì)算同生日的概率。假設(shè)一共有365個(gè)生日(只考慮月、日),而且各生日的概率是相等的(這里忽略了閏年的情況以及可能存在的出生日期分布的不均勻)。設(shè)一個(gè)班有n個(gè)人,當(dāng)n大于365時(shí)至少兩個(gè)人生日相同是必然事件。當(dāng)n小于等于365時(shí),我們可以計(jì)算P{至少有兩人同生日}=1-P{n個(gè)人生日彼此不同},這時(shí),n個(gè)人的生日可取值數(shù)為365n
,而n個(gè)人彼此不同的可能數(shù)為365中取n個(gè)的排列數(shù),彼此不同的概率為P3n65
。因此,為了計(jì)算n=1,2,...,365的情況下的同生日概率,可以用如下循環(huán)實(shí)現(xiàn):第四講-程序設(shè)計(jì)>x=numeric(365)>for(iin1:365){x[i]=1for(jin0:(i-1))x[i]=x[i]*(365-j)/365x[i]<-1-x[i]}
這段程序運(yùn)行了36秒。我們可以盡量用向量運(yùn)算來實(shí)現(xiàn),速度要快得多:>x<-numeric(365)>for(nin1:365){x[n]=1-prod((365:(365-n+1))/365)}
這段程序只用了1秒。注意不能直接去計(jì)算365!,這會(huì)超出數(shù)值表示范圍。第四講-程序設(shè)計(jì)我們有時(shí)候需要在某個(gè)判定條件成立的時(shí)候開始循環(huán),一旦條件不成立,就終止循環(huán),這時(shí)可以用while循環(huán)語句。while循環(huán)是在開始處判斷循環(huán)條件的,用法為:while(condition){expression}表示在condition成立的時(shí)候,執(zhí)行expression。例:一段二分法解方程的程序。>eps<-1e-5;>while(b-a>eps){c<-(a+b)/2;if(f(c)>0){b<-c}else{a<-c}}while語句
第四講-程序設(shè)計(jì)例:1000以內(nèi)Fibonacci數(shù)列的生成>f<-1;f[2]<-1;i<-1;>while(f[i]+f[i+1]<1000){f[i+2]<-f[i]+f[i+1]i<-i+1}
>f[1]1123581321345589144[13]233377610987第四講-程序設(shè)計(jì)repeat語句是while不一樣,把條件加在末尾,依賴break命令跳出循環(huán),基本用法是:repeat{expressions;if(condition)break}表示一直重復(fù)表達(dá)式的計(jì)算,知道condition成立的時(shí)候,跳出循環(huán)。repeat語句
第四講-程序設(shè)計(jì)例(續(xù)):用repeat語句生成1000以內(nèi)Fibonacci數(shù)列>f<-1;f[2]<-1;i<-1;>repeat{f[i+2]<-f[i]+f[i+1];i<-i+1;if(f[i]+f[i+1]>=1000)break;}
>f[1]1123581321345589144[13]233377610987第四講-程序設(shè)計(jì)編寫自己的函數(shù)R允許用戶創(chuàng)建自己的函數(shù)。事實(shí)上,R本身提供的絕大多數(shù)函數(shù)如sum(),plot()等,是編寫人員寫在R中的,與用戶自己創(chuàng)建的函數(shù)沒有本質(zhì)上的區(qū)別。R中函數(shù)定義的一般格式為
<-function(arg1,arg2,…){expressions}其中arg是函數(shù)的參數(shù)(自變量);expressions是一組表達(dá)式;放在程序最后一行的是返回值,也可以加return()命令返回指定的內(nèi)容,返回值可以是向量、數(shù)組、列表或數(shù)據(jù)框。定義函數(shù)可以直接在命令行進(jìn)行編寫,例如>hello=function(){cat("Hello,world\n");第四講-程序設(shè)計(jì)>hello#查看函數(shù)具體內(nèi)容
function(){cat("Hello,world\n");}>hello()#運(yùn)行函數(shù)
Hello,world
函數(shù)體為一個(gè)復(fù)合表達(dá)式,各表達(dá)式的之間用換行或分號(hào)分開。不帶括號(hào)調(diào)用函數(shù)顯示函數(shù)定義,而不是調(diào)用函數(shù)。在命令行輸入函數(shù)程序很不方便修改,所以我們一般是打開一個(gè)其他的編輯程序(如Windows的記事本),輸入以上函數(shù)定義,保存文件,比如保存到了C:\R\hello.R,我們就可以用>source(“Hi.R")運(yùn)行文件中的程序。實(shí)際上,用source()運(yùn)行的程序不限于函數(shù)定義,任何R程序都可以用這種方式編好再運(yùn)行,效果與在命令行直接輸入是一樣的。第四講-程序設(shè)計(jì)對于一個(gè)已有定義的函數(shù),可以用fix()函數(shù)來修改,如:>fix(hello)
將打開一個(gè)編輯窗口顯示函數(shù)的定義,修改后關(guān)閉窗口函數(shù)就被修改了。fix()調(diào)用的編輯程序缺省為記事本,可以用“options(editor="編輯程序名")”來指定自己喜歡的編輯程序。函數(shù)可以帶參數(shù),可以返回值,例如:>larger<-function(x,y){y.is.bigger<-(y>x);x[y.is.bigger]<-y[y.is.bigger];x;}
這個(gè)函數(shù)輸入兩個(gè)向量(相同長度)x和y,然后把x中比y對應(yīng)元素小的元素替換為y中對應(yīng)元素,返回x的值。R返回值為函數(shù)體的最后一個(gè)表達(dá)式的值,不需要使用return()函數(shù)。不過,也可以使用“return()”函數(shù)從函數(shù)體返回調(diào)用者。第四講-程序設(shè)計(jì)參數(shù)(自變量)R函數(shù)調(diào)用方式很靈活,例如,如下函數(shù):>fsub=function(x,y)x-y
有兩個(gè)虛參數(shù)x和y,我們用它計(jì)算100-45,可以調(diào)用fsub(100,45),或fsub(x=100,y=45),或fsub(y=45,x=100),或fsub(y=45,100)。即調(diào)用時(shí)實(shí)參與虛參可以按次序結(jié)合,也可以直接指定虛參名結(jié)合。實(shí)參先與指定了名字的虛參結(jié)合,沒有指定名字的按次序與剩下的虛參結(jié)合。函數(shù)在調(diào)用時(shí)可以不給出所有的實(shí)參,這需要在定義時(shí)為虛參指定缺省值。例如上面的函數(shù)改為:>fsub=function(x,y=0)x-y則調(diào)用時(shí)除了可以用以上的方式調(diào)用外還可以用fsub(100),fsub(x=100)等方式調(diào)用,只給出沒有缺省值的實(shí)參。第四講-程序設(shè)計(jì)即使沒有給虛參指定缺省值也可以在調(diào)用時(shí)省略某個(gè)虛參,然后函數(shù)體內(nèi)可以用missing()
函數(shù)判斷此虛參是否有對應(yīng)實(shí)參,如:>trans=function(x,scale){if(!missing(scale))x=scale*x…………}此函數(shù)當(dāng)給了scale的值時(shí)對自變量x乘以此值,否則保持原值。這種用法在其它語言中是極其少見的,R可以實(shí)現(xiàn)這一點(diǎn)是因?yàn)镽的函數(shù)調(diào)用在用到參數(shù)的值時(shí)才去計(jì)算這個(gè)參數(shù)的值(稱為“懶惰求值”),所以可以在調(diào)用時(shí)缺少某些參數(shù)而不被拒絕。R函數(shù)還可以有一個(gè)特殊的“...”虛參,表示所有不能匹配的實(shí)參,調(diào)用時(shí)如果有需要與其它虛參結(jié)合的實(shí)參必須用“虛參名=”的格式引入。例如:>fmin<-function(...){for(xinlist(...))cat(min(x),'\n')}>fmin(c(5,1,2),c(9,4,7))[1]14第四講-程序設(shè)計(jì)作用域函數(shù)的虛參完全是按值傳遞的,改變虛參的值不能改變對應(yīng)實(shí)參的值。例如:
>x=c(1,"abc")>x[1]"1"“abc">f=function(x){x[2]<-"!!";x}
>f(x)[1]"1""!!">x[1]"1"“abc"這個(gè)例子說明了函數(shù)體內(nèi)部的變量是局部的,賦值只針對函數(shù)體的變量,一旦函數(shù)運(yùn)行結(jié)束以后,不改變?nèi)肿兞康闹?。第四講-程序設(shè)計(jì)函數(shù)體內(nèi)的變量也是局部的,對函數(shù)體內(nèi)的變量賦值當(dāng)函數(shù)結(jié)束運(yùn)行后變量值就刪除了,不影響原來同名變量的值。例如:>x<-2>f<-function(){print(x);x=20}>f()[1]2>x
[1]2這個(gè)例子中原來有一個(gè)變量x值為2,函數(shù)中為變量x賦值20,但函數(shù)運(yùn)行完后原來的x值并未變化。但是也要注意,函數(shù)中的顯示函數(shù)調(diào)用時(shí)局部變量x還沒有賦值,顯示的是全局變量x的值。這是R編程比較容易出問題的地方:你用到了一個(gè)局部變量的值,你沒有意識(shí)到這個(gè)局部變量還沒有賦值,而程序卻沒有出錯(cuò),因?yàn)檫@個(gè)變量已有全局定義。第四講-程序設(shè)計(jì)R程序設(shè)計(jì)注意要點(diǎn)對于復(fù)雜一些的計(jì)算問題我們應(yīng)該編寫成函數(shù)。這樣做的好處是編寫一次可以重復(fù)使用,并且可以很容易地修改函數(shù)內(nèi)的變量名是局部的,運(yùn)行函數(shù)不會(huì)使函數(shù)內(nèi)的局部變量被保存到當(dāng)前的工作空間,可以避免在交互狀態(tài)下直接賦值定義很多變量使得工作空間雜亂無章。第四講-程序設(shè)計(jì)編寫函數(shù)是要注意:可讀性(readability).可理解性(understandability).
具體要做到:采用結(jié)構(gòu)化、模塊化編程;增加必要的注釋;使用意義明確的名字作為變量名,切忌用人名或者寵物名;行前縮進(jìn),使程序有層次感。第四講-程序設(shè)計(jì)工作空間管理R在運(yùn)行時(shí)保持一個(gè)變量搜索路徑表,要讀取某變量時(shí)依次在此路徑表中查找,返回找到的第一個(gè);給變量賦值時(shí)在搜索路徑的第一個(gè)位置賦值。但是,在函數(shù)內(nèi)部,搜索路徑表第一個(gè)位置是局部變量名空間,所以變量賦值是局部賦值,被賦值的變量只在函數(shù)運(yùn)行期間有效。用ls()函數(shù)可以查看當(dāng)前工作空間保存的變量和函數(shù),用rm()函數(shù)可以剔除不想要的對象。如:>ls()(或objects())
第四講-程序設(shè)計(jì)
[1]"A""Ai""b""cl""cl.f""fit1""g1""marks""ns"[10]"p1""rec""tmp.x""x""x1""x2""x3""y"
>rm(x,x1,x2,x3)>ls()[1]"A""Ai""b""cl""cl.f""fit1""g1""marks""ns"[10]"p1""rec""tmp.x""y"
ls()可以指定一個(gè)pattern參數(shù),此參數(shù)定義一個(gè)匹配模式,只返回符合模式的對象名。模式格式是UNIX中g(shù)rep的格式。比如,ls(pattern="tmp[.]")可以返回所有以“tmp.”開頭的對象名。rm()可以指定一個(gè)名為list的參數(shù)給出要?jiǎng)h除的對象名,所以rm(list=ls(pattern=“tmp[.]”))可以刪除所有以“tmp.”開頭的對象名。>rm(list=ls())
刪除所有對象。第四講-程序設(shè)計(jì)程序設(shè)計(jì)舉例設(shè)計(jì)R程序是很容易的,在初學(xué)時(shí)我們只要使用我們從一般程序設(shè)計(jì)中學(xué)來的知識(shí)并充分利用R中現(xiàn)成的各種算法及繪圖函數(shù)就可以了。但是,如果要用R編制計(jì)算量較大的程序,或者程序需要發(fā)表,就需要注意R程序設(shè)計(jì)的一些技巧。用R語言開發(fā)算法,最重要的一點(diǎn)是要記住R是一個(gè)向量語言,計(jì)算應(yīng)該盡量通過向量、矩陣運(yùn)算來進(jìn)行,或者使用R提供的現(xiàn)成的函數(shù),避免使用顯式循環(huán)。顯式循環(huán)會(huì)大大降低R的運(yùn)算速度,因?yàn)镽是解釋執(zhí)行的。第四講-程序設(shè)計(jì)>n=1:10;>x=sin(n*pi/10);>cat('x=',x)[1]x=0.3090170.58778530.8090170.951056510.95105650.8090170.58778530.3090171.224606e-16>fsin<-function(x){sin<-0;for(iin1:length(x)){sin[i]<-sin(x[i]*pi/10);}return(sin);}y<-1:10;fsin(y);[1]3.090170e-015.877853e-018.090170e-019.510565e-011.000000e+00[6]9.510565e-018.090170e-015.877853e-013.090170e-011.224606e-16例
對n=1,2,…,10,求xn=的值第四講-程序設(shè)計(jì)Money.Rmoney=10000years=0while(money<20000){years=years+1;money=money*(1+2.52/100)}
例
設(shè)銀行年利率為2.52%。將10000元錢存入銀行,問至少多長時(shí)間會(huì)連本帶利翻一番?>source(Money.R');years;money;[1]28[1]20074.31第四講-程序設(shè)計(jì)>fun<-function(x){y=numeric(length(x));y[x>1]=x[x>1]^2+1;y[x<=1]=2*x[x<=1];cat('fun=',y)}>fun(c(1,2,3))[1]fun=2510例第四講-程序設(shè)計(jì)存款函數(shù)deposit()deposit<-function(amount,total){if(amount<=0)stop("Depositsmustbepositive!\n")total<-total+amount;cat
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲(chǔ)空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 小學(xué)藝術(shù)教育年度發(fā)展報(bào)告
- 長春健康職業(yè)學(xué)院《測繪案例分析》2023-2024學(xué)年第一學(xué)期期末試卷
- 食品加工取樣與檢測流程
- AR眼鏡產(chǎn)品投資導(dǎo)覽模板
- 同學(xué)聚會(huì)講話稿
- 二零二五年度未成年人監(jiān)護(hù)權(quán)及撫養(yǎng)費(fèi)支付協(xié)議書3篇
- 重慶市部分區(qū)2024-2025學(xué)年高二(上)期末物理試卷(含答案)
- 福建省泉州市泉港區(qū)2024-2025學(xué)年七年級(jí)上學(xué)期1月期末生物學(xué)試題(含答案)
- 二零二五年度綠色建筑設(shè)計(jì)與施工一體化建設(shè)工程技術(shù)咨詢合同05013篇
- 宿州職業(yè)技術(shù)學(xué)院《python與數(shù)據(jù)處理基礎(chǔ)》2023-2024學(xué)年第一學(xué)期期末試卷
- 2024年石家莊正定國際機(jī)場改擴(kuò)建工程合同
- GB/T 44823-2024綠色礦山評(píng)價(jià)通則
- 華為C語言通用編程規(guī)范
- 搞笑詩朗誦《生活》4人
- 團(tuán)建活動(dòng)滿意度調(diào)查問卷
- 數(shù)獨(dú)題目難度系數(shù)3級(jí)共100題后附參考答案
- 漂亮的可編輯顏色魚骨圖PPT模板
- 齊魯醫(yī)學(xué)數(shù)字疼痛評(píng)分表
- GB∕T 7588.1-2020 電梯制造與安裝安全規(guī)范 第1部分:乘客電梯和載貨電梯
- 植物種植施工方案與技術(shù)措施
- 空調(diào)工程竣工驗(yàn)收單(共1頁)
評(píng)論
0/150
提交評(píng)論