程式設計第一堂課的心得─關於R還有一些重要概念
這是統計系系上開的必修課,跟資工系的程式設計並不一樣,目前是學習使用軟體R來處理統計上的問題。今天講完R基本指令、定義方式,試著寫算術平均數、變異數、標準差、absolute deviation(這個中文不曉得怎麼翻譯)的function(一套解決問題的作用程序,我的疑問是程式上講的function似乎和數學上的function不太一樣,最後再多談一些)。
基本指令、定義方式
對一個代號x定義值,可藉由輸入
x=4或
x<-4
想要顯示x的結果,就輸入x然後按enter就行了
x
基本指令、定義方式
對一個代號x定義值,可藉由輸入
x=4或
x<-4
想要顯示x的結果,就輸入x然後按enter就行了
x
[1] 4前面那個[1]是數數的,只是現在東西不夠多,如果夠多的話到下一列,下一列的開頭也許就會顯示[11]或[26]之類的,意思是這一列從第11個或第26個開始,依此類推…
對一個代號x定義為行向量,可藉由輸入
x=c(4,5,6)或
x<-c(4,5,6)注意,這時候x到底是什麼呢?x已經變為一個向量,對x作為向量的定義已經覆蓋了之前整數的定義,所以x=(4,5,6),一個代號不能有兩個意義
對一個代號x定義為行向量,可藉由輸入
x=c(4,5,6)或
x<-c(4,5,6)注意,這時候x到底是什麼呢?x已經變為一個向量,對x作為向量的定義已經覆蓋了之前整數的定義,所以x=(4,5,6),一個代號不能有兩個意義
x
[1] 4 5 6
x[1]是對程式要求顯示向量第一個component或代表向量第一個component的意思,例如現在x=(4,5,6)
x[1]
[1] 4
想要對程式要求顯示多個component,例如第一個和第二個,可藉由打
x[c(1,2)]就會顯示
x[1]是對程式要求顯示向量第一個component或代表向量第一個component的意思,例如現在x=(4,5,6)
x[1]
[1] 4
想要對程式要求顯示多個component,例如第一個和第二個,可藉由打
x[c(1,2)]就會顯示
[1] 4 5想要哪些欄位就仿照這個形式輸入數字,就會顯示第幾欄位的component了
特殊的:a<-c(1:10),是定義a為一個10個components的行向量,且component正是從1排到10,不過如果是較一般的向量,component較不規則的,還是要自己一個一個輸入數字。
a
特殊的:a<-c(1:10),是定義a為一個10個components的行向量,且component正是從1排到10,不過如果是較一般的向量,component較不規則的,還是要自己一個一個輸入數字。
a
[1] 1 2 3 4 5 6 7 8 9 10
關於四則運算和次方,用的符號是+-*/^,這就不多講了,就像一般算式一樣輸入進去,R讀的懂
ls():這是R內建的function,我覺得它非常重要,在有時候可能也會非常好用,它的功能是看working space裡的東西,就是你已經定義了什麼,像剛剛已經對x、a定義了,如果我使用它
關於四則運算和次方,用的符號是+-*/^,這就不多講了,就像一般算式一樣輸入進去,R讀的懂
ls():這是R內建的function,我覺得它非常重要,在有時候可能也會非常好用,它的功能是看working space裡的東西,就是你已經定義了什麼,像剛剛已經對x、a定義了,如果我使用它
ls()
[1] “x” “a”代表說我現在有兩個東西─x和a可用,就好像是找工具箱裡有哪些現成工具,如果沒有你要的工具,在情況許可下,你可以自己創造,這也是資訊工程師和其他類的工程師很不一樣的地方
另外一個系統內建function是length(),()內輸入向量,它會算出這個向量有幾個component,例如:
n=length(x)
[1] “x” “a”代表說我現在有兩個東西─x和a可用,就好像是找工具箱裡有哪些現成工具,如果沒有你要的工具,在情況許可下,你可以自己創造,這也是資訊工程師和其他類的工程師很不一樣的地方
另外一個系統內建function是length(),()內輸入向量,它會算出這個向量有幾個component,例如:
n=length(x)
n
[1] 3
x=(4,5,6)它有3個component,因此n=3這跟數學上向量長度的定義不太一樣,數學上是把每個component平方,取和,再開跟號
基本的指令和定義方式學會了,現在要做平均數、變異數、標準差的function,觀察公式、從所求想起,裡頭有一個共同牽涉到的運算─summation,而這也是之前的簡單指令所很難表達的,一個一個加起來?該如何用程式做出summation這個動作?有一個解法是for迴圈,for迴圈可「重複執行同一性質的某動作」,平均數就是把一群數加起來再除以它們的總數,過程就是一直+,for迴圈的特性正好符合我們的需求,不過且慢,在談技術細節之前,我要談一件更重要的事情,看起來也許平淡無奇,其中牽涉到思考基本規則。
我們小學學過一個四則運算基本觀念,若是碰到括號,括號內的運算要先做,例如(4+5)x3,雖然x的priority(優先權)比+高,但()更高,所以是先做(4+5)=9,再9x3=27,運算有priority高低之分,+-x/()的priority若是沒有差別,一律從最前面做到尾,()此時沒有任何意義,一些基本規則也不再成立,例如2x(3+5)=6+5=11(原有的分配律不成立),以前(2+3+4+5)x(6+7+8+9)這種算式在處理上完全沒問題,但在「一律從最前面做到尾」的規則下,怎表?一個算式表不出來,得寫兩個算式,先2+3+4+5=14,再6+7+8+9x14,這只是簡單的先做兩堆的和再相乘而已,如果乘更多項或除更多項,得寫幾個算式才能解決啊?捨棄priority()最高、x/次之、+-最低的模式,光是表達算式上的弊病就讓人對其敬而遠之了,這麼定的唯一效用可能是讓小孩子一開始學初等算術覺得簡單些了,但過不久他們可能會開始厭惡數學課,因為總是要寫好多算式,搞的糊里糊塗的了。(一時只想到表達形式上的問題,可能還有其他問題是我沒想到的)
x=(4,5,6)它有3個component,因此n=3這跟數學上向量長度的定義不太一樣,數學上是把每個component平方,取和,再開跟號
基本的指令和定義方式學會了,現在要做平均數、變異數、標準差的function,觀察公式、從所求想起,裡頭有一個共同牽涉到的運算─summation,而這也是之前的簡單指令所很難表達的,一個一個加起來?該如何用程式做出summation這個動作?有一個解法是for迴圈,for迴圈可「重複執行同一性質的某動作」,平均數就是把一群數加起來再除以它們的總數,過程就是一直+,for迴圈的特性正好符合我們的需求,不過且慢,在談技術細節之前,我要談一件更重要的事情,看起來也許平淡無奇,其中牽涉到思考基本規則。
我們小學學過一個四則運算基本觀念,若是碰到括號,括號內的運算要先做,例如(4+5)x3,雖然x的priority(優先權)比+高,但()更高,所以是先做(4+5)=9,再9x3=27,運算有priority高低之分,+-x/()的priority若是沒有差別,一律從最前面做到尾,()此時沒有任何意義,一些基本規則也不再成立,例如2x(3+5)=6+5=11(原有的分配律不成立),以前(2+3+4+5)x(6+7+8+9)這種算式在處理上完全沒問題,但在「一律從最前面做到尾」的規則下,怎表?一個算式表不出來,得寫兩個算式,先2+3+4+5=14,再6+7+8+9x14,這只是簡單的先做兩堆的和再相乘而已,如果乘更多項或除更多項,得寫幾個算式才能解決啊?捨棄priority()最高、x/次之、+-最低的模式,光是表達算式上的弊病就讓人對其敬而遠之了,這麼定的唯一效用可能是讓小孩子一開始學初等算術覺得簡單些了,但過不久他們可能會開始厭惡數學課,因為總是要寫好多算式,搞的糊里糊塗的了。(一時只想到表達形式上的問題,可能還有其他問題是我沒想到的)
sum<-function(x){ n<-length(x)
temp<-0
for( i in 1:n)temp<-temp+x[i]
return(temp)
return(temp)
}
假定這時候x=(1,2,3,…,n)
假定這時候x=(1,2,3,…,n)
第一行的意思是定義一個function叫做sum,{ }裡是function的內容,n<-length(x)就是把n定為向量x的component數目;第二行和第三行特別一些,定義temp為0(或者說賦值temp為0,賦值是個好字,很白話,就是給它一個值,在跟一個同學聊天時講到的),for( i in 1:n)意思是後面的程序是從i=1開始做,再來i=2, i=3…, 到i=n,看到那個<-,應該也猜到式子的priority了吧,沒錯,就是先把temp+x[1],再把這個值給temp,覆蓋原本為0的定義,還記得「一個代號不能有兩個意義」吧,經過一輪後temp=0+1=1了,第二輪temp=1+2=3…,加到n的時候,temp就會是1,2,3,…累加到n了,獲得了總和,但程式有input、output,兩個都非常重要,必須規範清楚,現在要function輸出什麼?總和,那就是temp了,return(temp)是把temp丟出去的意思,這樣結果才會呈現,不然會沒有任何東西,終於達到目的了。
其他的是比較零碎的心得和筆記,短短的句子,就直接條列在下面了,這對其他人可能較無價值
1.必須清楚規範input、output
2.程式裡運用的物件都必須定義清楚其他的是比較零碎的心得和筆記,短短的句子,就直接條列在下面了,這對其他人可能較無價值
1.必須清楚規範input、output
3.思考:想要什麼作用、作用的order、已定義的代號、未定義的代號
4.一個代號只能有一個意義,不能同時有兩個意義,這點像數學上function定義域裡的元素
5.當我先前已經定義好某function f,我在g裡可直接引用f來作用
6.function內部設的東西不會出現在working space或者覆寫原有的代號意義,舉例來說,在外部我已定義n=10,在function內部我又使用了n這個代號,我在function內定n=8,並不再改變它,在function的作用期間遇到n皆為8,但後來查working space裡的n還是10,所以function內部對代號的設定似乎不會改變working space的設定;但在function有用到n,卻沒在function內定義n,那function會拿working space裡的n來用,也就是視n為10
沒時間講function了,而且根據經驗,如果拖過隔天,這篇文章很可能就發不出去了,function在程式上和在數學上的意義似乎不太一樣,改在別篇文章再談,應該不會太長。
跟我現在的機電程式課一樣,要寫MATLAB,我們似乎都要學跟自己相關的計算程式,MATLAB可以算矩陣反矩陣10x10的矩陣不用1秒就跑出來了。
回覆刪除另外一件事,coding style很重要,一些小細節的習慣可能在寫小程式看不出有什麼好壞,但在大型一點的程式就會看出來了
刪除http://blog.vgod.tw/2008/07/05/%e8%bf%bd%e6%b1%82%e7%a5%9e%e4%b9%8e%e5%85%b6%e6%8a%80%e7%9a%84%e7%a8%8b%e5%bc%8f%e8%a8%ad%e8%a8%88%e4%b9%8b%e9%81%93%e4%b8%80%ef%bc%89/
我中間段落打的「運算有priority高低之分」,是打文章中途一時想到的,以前我也沒想過,可能真的很重要啊...