R語言
我理解,你的意思是循環的判斷,當最后一項為1,且第一項為0 的時候,那么這兩者交換; 但是,代碼表示的邏輯是,不論是不是最后一項,只要不滿足當前項為1,下一項為0,就做else塊中的代碼;可見當i=1,5,6,7,8,9,10時,都執行了else中的代碼; 最后,按照你的風格,修改如下: redrowmove<-function(x){ for(i in 1:(length(x)-1)){ if(x[i]==1 && x[i+1]==0){ x[i]=0 x[i+1]=1 } } if(x[length(x)]==1 && x[1]==0){ x[length(x)]=0 x[1]=1 } return(x)}。
關于R語言函數
R語言實際上是函數的集合,用戶可以使用base,stats等包中的基本函數,也可以自己編寫函數完成一定的功能。
但是初學者往往認為編寫R函數十分困難,或者難以理解。這里對如何編寫R函數進行簡要的介紹。
函數是對一些程序語句的封裝。換句話說,編寫函數,可以減少人們對重復代碼書寫,從而讓R腳本程序更為簡潔,高效。
同時也增加了可讀性。一個函數往往完成一項特定的功能。
例如,求標準差sd,求平均值,求生物多樣性指數等。R數據分析,就是依靠調用各種函數來完成的。
但是編寫函數也不是輕而易舉就能完成的,需要首先經過大量的編程訓練。特別是對R中數據的類型,邏輯判別、下標、循環等內容有一定了解之后,才好開始編寫函數。
對于初學者來說,最好的方法就是研究現有的R函數。因為R程序包都是開源的,所有代碼可見。
研究現有的R函數能夠使編程水平迅速提高。 R函數無需首先聲明變量的類型,大部分情況下不需要進行初始化。
一個完整的R函數,需要包括函數名稱,函數聲明,函數參數以及函數體幾部分。1. 函數名稱,即要編寫的函數名稱,這一名稱就作為將來調用R函數的依據。
2. 函數聲明,包括 <- function, 即聲明該對象的類型為函數。3. 函數參數,這里是輸入的數據,函數參數是一個虛擬出來的一個對象。
函數參數所等于的數據,就是在函數體內部將要處理的值,或者對應的數據類型。 函數體內部的程序語句進行數據處理,就是對參數的值進行處理 ,這種處理只在調用函數的時候才會發生。
函數的參數可以有多種類型。R help的界面對每個函數,及其參數的意義及所需的數據類型都進行了說明。
4. 函數體常常包括三部分.(1). 異常處理輸入的數據不能滿足函數計算的要求,或者類型不符, 這時候一定要設計相應的機制告訴用戶,輸入的數據在什么地方有錯誤。 錯誤又分為兩種。
第一種, 如果輸入的數據錯誤不是很嚴重,可以經過轉換,變為符合處理要求的數據時, 此時只需要給用戶一個提醒,告知數據類型不符,但是函數本身已經 進行了相應的轉換。第二種,數據完全不符合要求,這種情況下,就 要終止函數的運行,而告知因為什么,函數不能運行。
這樣,用戶在 使用函數的情況先才不至于茫然。(2). 運算過程包括具體的運算步驟。
運算過程和該函數要完成的功能有關。R運算過程中,應該盡量減少循環的使用,特別是嵌套循環。
R提供了 apply,replicate等一系列函數,來代替循環,應該盡量應用這些函數, 提高效率。 如果在R中實在太慢,那么核心部分只能依靠C或者Fortran 等語言編寫,然后再用R調用這些編譯好的模塊,達到更高的效率。
運算過程中,需要大量用到if等條件作為判別的標準。if和while都是需要數據TRUE/FALSE這樣的邏輯類型變量,這就意味著,if內部,往往是對條件的判別,例如 *, *, *c等等,或者對大小的比較,如,if(x > 0), if(x == 1), if(length(x)== 3)等等。
if后面,如果是1行,則花括號可以省略,否則就必須要將所有的語句都放在花括號中。這和循環是一致的。
例子:## if與條件判斷* <- function(a, b, method = "add"){ if(method == "add") { ## 如果if或者for/while; res <- a + b ## 等后面的語句只有一行,則無需使用花括號。} if(method == "subtract"){ res <- a - b } return(res) ## 返回值}### 檢驗結果*(a = 10, b = 8, method = "add")*(a = 10, b = 8, method = "substract")。