R語言中的初等數學計算

前言

1.大部分參考張丹(Conan)的R的極客理想系列文章《R語言中的數學計算》,對此表示感謝。
http://blog.fens.me/r-mathematics/
2.補充、解釋和學習,記錄並便於今後的查詢。

目錄

  1. 基本計算
  2. 三角函數計算
  3. 複數計算
  4. 方程計算

一、基本計算

(一)、四則運算: 加減乘除、餘數、整除、絕對值、判斷正負

(1)判斷正負

> sign(-2:3)
[1] -1 -1  0  1  1  1

#sign函數用以判斷數值型向量的正負,0表示向量爲0,-1表示向量爲負,+1表示向量爲正

(二)、數學計算: 冪、自然常數e的冪、平方根和對數

> a<-10;b<-5;c<-4

(1)冪

> c^b;c^-b;c^(b/10)
[1] 1024
[1] 0.0009765625
[1] 2

(2)自然常數e

> exp(1)
[1] 2.718282

(3)自然常數e的冪

> exp(3)
[1] 20.08554

(4)平方根

> sqrt(c)
[1] 2

(5)以2爲底的對數

> log2(c)
[1] 2

(6) 以10爲底的對數

> log10(b)
[1] 0.69897

(7)自定義底的對數

> log(c,base = 2)
[1] 2

#base是底,c爲所求值

(8)自然常數e的對數

> log(a,base=exp(1))
[1] 2.302585

(9)指數對數操作

> log(a^b,base=a)
[1] 5
> log(exp(3))
[1] 3

#若省略底數base,則默認自然常數e爲底

(三)、比較計算: ==、>、<、!=、<=、>=、isTRUE、identical

(1)!=

> a!=b
[1] TRUE

#!=表示“不等於”

(2)isTRUE

> isTRUE(a<b)
[1] TRUE
> isTRUE(a>b)
[1] FALSE

#判斷括號內是否爲True

(3)identical/精確比較兩個對象

> identical(1, as.integer(1))
[1] FALSE
> identical(NaN, -NaN)
[1] TRUE
> f <- function(x) x
> g <- compiler::cmpfun(f)
> identical(f, g)
[1] TRUE

##
1.Numeric或者"double" 是R優先選擇的存儲數值的方式。需要注意的是, 有的時候認爲Numeric是"integer""double"的統稱。
2.Integer是整數。一般不管有沒有小數點的數字, R默認存成Numeric, 這個時候需要使用as.integer函數強制去把數存爲Integer。
3.NA表示缺失值,即“Missing value”,是“not available”的縮寫。主要會在從文件或數據庫讀取數據時遇到,或者將一個向量的長度擴展會出現NA值。
4.Inf和-Inf就是指正負無窮,或者除以0時會出現。
5.NaN表示無意義,即“not a number”(例如Inf-Inf/0/0)。
6.另外,R語言中還有一種Null對象,一般被用在函數參數中,表示該參數沒有被賦予任何值,或者某些函數返回值爲Null。
7.compiler可以將R的程式碼編譯後再執行,可增加執行的速度。
8.編譯與解釋的區別:
編譯:編譯器會把源文件先處理一遍,生成一個目標文件,再執行(先煮火鍋再吃菜,效率高)。
解釋:邊處理源文件,邊執行(邊煮火鍋邊吃菜,效率低)。

(四)、邏輯計算: &、|、&&、||、xor

> x<-c(0,1,0,1)
> y<-c(0,0,1,1)

(1)只比較第一個元素(&&, ||)

> x && y;x || y
[1] FALSE
[1] FALSE

#當x和y的第一個元素均爲“真”時,其結果爲TRUE,否則爲FALSE

(2)S4對象的邏輯運算,比較所有元素(&, |)

> x & y;x | y
[1] FALSE FALSE FALSE  TRUE
[1] FALSE  TRUE  TRUE  TRUE

(3)異或

> xor(x,y)
[1] FALSE  TRUE  TRUE FALSE
> xor(x,!y)
[1]  TRUE FALSE FALSE  TRUE

#xor爲異或,兩值不等爲真,兩值相等爲假

(五)、約數計算:ceiling、floor、trunc、round、signif

(1)向上取整

> ceiling(5.4)
[1] 6

(2)向下取整

> floor(5.8)
[1] 5

(3)取整數

> trunc(3.9)
[1] 3

(4)四捨五入

> round(5.8)

(5)四捨五入,保留2位小數

> round(5.8833, 2)
[1] 5.88

(6)四捨五入,保留前2位整數

> signif(5990000,2)
[1] 6e+06

(六)、數組計算: 最大、最小、範圍、求和、均值、 加權平均、連乘、差分、秩、中位數、分位數、任意數、全體數

> d<-seq(1,10,2);d
[1] 1 3 5 7 9

(1)加權平均

> weighted.mean(d,rep(1,5))
[1] 5
> weighted.mean(d,c(1,1,2,2,2))
[1] 5.75

(2)連乘

> prod(1:5)
[1] 120

(3)差分

> diff(d)
[1] 2 2 2 2

#1.差分:差分計算,是用向量的後一項減去前一項,所獲得的差值,差分的結果反映了離散量之間的一種變化。

(4)秩

> rank(d)
[1] 1 2 3 4 5

(5)分位數

> quantile(d)
0%  25%  50%  75% 100%
1    3    5    7    9

(6)任意any,全體all

> e<-seq(-3,3);e
[1] -3 -2 -1  0  1  2  3
> any(e<0);all(e<0)
[1] TRUE
[1] FALSE

(七)、排列組合計算: 階乘, 組合, 排列

(1)5!階乘

> factorial(5)
[1] 120

(2)組合, 從5箇中選出2個

> choose(5, 2)
[1] 10

(3)列出從5箇中選出2個的組合所有項

> combn(5,2)
     [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10]
[1,]    1    1    1    1    2    2    2    3    3     4
[2,]    2    3    4    5    3    4    5    4    5     5

(4)計算0:10的組合個數

> for (n in 0:10) print(choose(n, k = 0:n))
[1] 1
[1] 1 1
[1] 1 2 1
[1] 1 3 3 1
[1] 1 4 6 4 1
[1] 1 5 10 10 5 1
[1] 1 6 15 20 15 6 1
[1] 1 7 21 35 35 21 7 1
[1] 1 8 28 56 70 56 28 8 1
[1] 1 9 36 84 126 126 84 36 9 1
[1] 1 10 45 120 210 252 210 120 45 10 1

(5)排列,從5箇中選出2個

> choose(5, 2)*factorial(2)
[1] 20

(八)、累積計算: 累加, 累乘, 最小累積, 最大累積

(1)累加

> cumsum(1:5)
[1]  1  3  6 10 15

(2)累乘

> cumprod(1:5)
[1]   1   2   6  24 120
> e<-seq(-3,3);e
[1] -3 -2 -1  0  1  2  3

(3)最小累積cummin

> cummin(e)
[1] -3 -3 -3 -3 -3 -3 -3

#新向量的增加項,爲e向量中累積的最小值

(4)最大累積cummax

> cummax(e)
[1] -3 -2 -1  0  1  2  3

#新向量的增加項,爲e向量中累積的最大值

(九)、兩個數組計算: 交集、並集、差集、數組是相等、取唯一、查匹配元素的索引、找重複元素索引

定義兩個數組向量

> x <- c(9:20, 1:5, 3:7, 0:8);x
[1]  9 10 11 12 13 14 15 16 17 18 19 20  1  2  3  4  5
[18]  3  4  5  6  7  0  1  2  3  4  5  6  7  8
> y<- 1:10;y
[1]  1  2  3  4  5  6  7  8  9 10

(1)交集

> intersect(x,y)
[1]  9 10  1  2  3  4  5  6  7  8

(2)並集

> union(x,y)
 [1]  9 10 11 12 13 14 15 16 17 18 19 20  1  2  3  4  5
[18]  6  7  0  8

#也會剔除各自集合內重複的元素

(3)差集,從x中排除y

> setdiff(x,y)
 [1] 11 12 13 14 15 16 17 18 19 20  0

(4)判斷是否相等

> setequal(x, y)
[1] FALSE

(5)取唯一

> unique(c(x,y))
 [1]  9 10 11 12 13 14 15 16 17 18 19 20  1  2  3  4  5
[18]  6  7  0  8

(6)找到x在y中存在的元素的索引(下標)

> which(x %in% y)
 [1]  1  2 13 14 15 16 17 18 19 20 21 22 24 25 26 27 28
[18] 29 30 31
> which(is.element(x,y))
 [1]  1  2 13 14 15 16 17 18 19 20 21 22 24 25 26 27 28
[18] 29 30 31

#is.element(x,y):判斷x是否爲y內element(元素),輸出爲邏輯判斷值(FALSE或TRUE) 

(7)找到重複元素的索引(下標)

> which(duplicated(x))
 [1] 18 19 20 24 25 26 27 28 29 30

二、三角函數計算

(一)、三角函數

(1)三角函數畫圖

# 加載ggplot2的庫
> library(ggplot2)
> library(scales)
# x座標
> x<-seq(-2*pi,2*pi,by=0.01)

# y座標
>s1<-data.frame(x,y=sin(x),type=rep('sin',length(x)))
# 正弦

>s2<-data.frame(x,y=cos(x),type=rep('cos',length(x)))
# 餘弦

>s3<-data.frame(x,y=tan(x),type=rep('tan',length(x)))
# 正切

>s4<-data.frame(x,y=1/tan(x),type=rep('cot',length(x)))
# 餘切

>s5<-data.frame(x,y=1/sin(x),type=rep('sec',length(x)))
# 正割

>s6<-data.frame(x,y=1/cos(x),type=rep('csc',length(x)))
# 餘割

>df<-rbind(s1,s2,s3,s4,s5,s6)

#
1.type參數用以定義每個點(x,y)的類型,不同的type可以用不同的顏色進行區分
2.r是row(行)的含義,rbind將s1-6沿“行”合併data.frame(形式上,像是縱向合併)。
# 用ggplot2畫圖
> g<-ggplot(df,aes(x,y))
> g<-g+geom_line(aes(colour=type,stat='identity'))
> g<-g+scale_y_continuous(limits=c(0, 2))
> g<-g+scale_x_continuous(breaks=seq(-2*pi,2*pi,by=pi),labels=c("-2*pi","-pi","0","pi","2*pi"))
> g

#
1.ggplot2的核心理念是將繪圖與數據分離,數據相關的繪圖與數據無關的繪圖分離。要使用ggplot2創建圖形對象,就要用到ggplot()函數。
2.基本語法
*圖形屬性(aes):圖形屬性決定了圖形的外觀,如字體大小、標籤位置及刻度線;
*映射(mapping):數據中的變量到圖形成分的映射;
*統計變換(stat):對數據進行彙總,如箱線圖:stat_boxplot、線圖:stat_abline、直方圖:stat_bin;
*標度(scale):決定了變量如何被映射到圖形屬性上;
*幾何對象(geom):用來展示數據的幾何對象,如geom_point,geom_bar,geom_abline
3.審美映射
p+geom_line(aes(size = rating))
p+geom_line(aes(colour = rating))

(二)、反三角函數

反正弦asin()
反餘弦acos()
反正切atan()

三、複數計算

(一)、創建一個複數

####(1)直接創建複數
> ai<-5+2i;ai
[1] 5+2i
> class(ai)
[1] "complex"

(2)通過complex()函數創建複數

> bi<-complex(real=5,imaginary=2);bi
[1] 5+2i
> is.complex(bi)
[1] TRUE

(3)實數部分

> Re(ai)
[1] 5

(4)虛數部分

> Im(ai)
[1] 2

(5)取模

> Mod(ai)
[1] 5.385165 

# sqrt(5^2+2^2) = 5.385165

(6)取輻角

> Arg(ai)
[1] 0.3805064

#複數的幅角是指複數在複平面上對應的向量和正向實數軸所成的有向角。

(7)取軛

> Conj(ai)
[1] 5-2i

#共軛複數,兩個實部相等,虛部互爲相反數的複數互爲共軛複數(conjugate complex number)。

(二)、複數四則運算

加法公式:(a+bi)+(c+di) = (a+c)+(b+d)i
減法公式:(a+bi)-(c+di)= (a-c)+(b-d)i
乘法公式:(a+bi)(c+di) = ac+adi+bci+bidi=ac+bdi^2+(ad+bc)i=(ac-bd)+(ad+bc)i
除法公式:(a+bi)/(c+di) = ((ac+bd)+(bc-ad)i)/(c^2+d^2)

(三)、複數開平方根

(1)在實數域,給-9開平方根

> sqrt(-9)
[1] NaN

(2)在複數域,給-9開平方根

> sqrt(complex(real=-9))
[1] 0+3i

四、方程計算

(一)、一元一次方程

一元一次方程:a*x+b=0,設a=5,b=10,求x?

# 定義方程函數
> f1 <- function (x, a, b) a*x+b

# 給a,b常數賦值
> a<-5;b<-10

# 在(-10,10)的區間,精確度爲0.0001位,計算方程的根
> result <- uniroot(f1,c(-10,10),a=a,b=b,tol=0.0001)

# 打印方程的根x
> result$root
[1] -2


#
1.uniroot()函數每次只能計算一個根,而且要求輸入的區間端點值必須是正負號相反的(原理是通過二分法進行求解)

以圖形展示方程:y = 5*x + 10

# 創建數據點
> x<-seq(-5,5,by=0.01)
> y<-f1(x,a,b)
> df<-data.frame(x,y)

# 用ggplot2來畫圖
> g<-ggplot(df,aes(x,y))
> g<-g+geom_line(col='red') #紅色直線
> g<-g+geom_point(aes(result$root,0),col="red",size=3) #點
> g<-g+geom_hline(yintercept=0)+geom_vline(xintercept=0) #座標軸
> g<-g+ggtitle(paste("y =",a,"* x +",b))
> g

#
1.hline水平線
2.vline豎直線

(二)、一元二次方程

一元二次方程:a*x^2+b*x+c=0,設a=1,b=5,c=6,求x?

> f2 <- function (x, a, b, c) a*x^2+b*x+c
> a<-1;b<-5;c<-6
> result <- uniroot(f2,c(0,-2),a=a,b=b,c=c,tol=0.0001)
> result$root
[1] -2


> result <- uniroot(f2,c(-4,-3),a=a,b=b,c=c,tol=0.0001)
> result$root
[1] -3

方程的兩個根,一個是-2,一個是-3。

由於uniroot()函數,每次只能計算一個根,而且要求輸入的區間端值,必須是正負號相反的。如果我們直接輸入一個(-10,0)這個區間,那麼uniroot()函數會出現錯誤。這應該是uniroot()爲了統計計算對一元多次方程而設計的,所以爲了使用uniroot()函數,我們需要取不同的區別來獲得方程的根。

以圖形展示方程:y = x^2 + 5*x + 6

# 創建數據點
> x<-seq(-5,1,by=0.01)
> y<-f2(x,a,b,c)
> df<-data.frame(x,y)

# 用ggplot2來畫圖
> g<-ggplot(df,aes(x,y))
> g<-g+geom_line(col='red') #紅色曲線
> g<-g+geom_hline(yintercept=0)+geom_vline(xintercept=0) #座標軸
> g<-g+ggtitle(paste("y =",a,"* x ^ 2 +",b,"* x +",c))
> g


我們從圖,並直接的看到了x的兩個根取值範圍。

(三)、一元三次方程

一元二次方程:a*x^3+b*x^2+c*x+d=0,設a=1,b=5,c=6,d=-11,求x?

> f3 <- function (x, a, b, c,d) a*x^3+b*x^2+c*x+d
> a<-1;b<-5;c<-6;d<--11
> result <- uniroot(f3,c(-5,5),a=a,b=b,c=c,d=d,tol=0.0001)
> result$root
[1] 0.9461458

如果我們設置對了取值區間,那麼一下就得到了方程的根。

以圖形展示方程:y = x^2 + 5*x + 6

# 創建數據點
> x<-seq(-5,5,by=0.01)
> y<-f3(x,a,b,c,d)
> df<-data.frame(x,y)

# 用ggplot2畫圖
> g<-ggplot(df,aes(x,y))
> g<-g+geom_line(col='red') # 3次曲線
> g<-g+geom_hline(yintercept=0)+geom_vline(yintercept=0) #座標軸
> g<-g+ggtitle(paste("y =",a,"* x ^ 3 +",b,"* x ^2 +",c,"* x + ",d))
> g

(四)、二元一次方程

R語言還可以解二次的方程組,當然計算方法,其實是利用於矩陣計算。

假設方程組:是以x1,x2兩個變量組成的方程組,求x1,x2的值

以矩陣形式,構建方程組

# 左矩陣
> lf<-matrix(c(3,5,1,2),nrow=2,byrow=TRUE)

# 右矩陣
> rf<-matrix(c(4,1),nrow=2)

# 計算結果
> result<-solve(lf,rf)
> result
     [,1]
[1,]    3
[2,]   -1

得方程組的解,x1, x2分別爲3和-1。

接下來,我們畫出這兩個線性方程的圖。設y=X2, x=X1,把原方程組變成兩個函數形式。

# 定義2個函數
> fy1<-function(x) (-3*x+4)/5
> fy2<-function(x) (-1*x+1)/2

# 定義數據
> x<-seq(-1,4,by=0.01)
> y1<-fy1(x)
> y2<-fy2(x)
> dy1<-data.frame(x,y=y1,type=paste("y=(-3*x+4)/5"))
> dy2<-data.frame(x,y=y2,type=paste("y=(-1*x+1)/2"))
> df <- rbind(dy1,dy2)

# 用ggplot2畫圖
> g<-ggplot(df,aes(x,y))
> g<-g+geom_line(aes(colour=type,stat='identity')) #2條直線
> g<-g+geom_hline(yintercept=0)+geom_vline(xintercept=0) #座標軸
> g


我們看到兩條直線交點的座標,就是方程組的兩個根。多元一次方程,同樣可以用這種方法來解得。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章