Hi,新的專欄內容:matlab vs R
這一次,是我打算學習 matlab 的開始,也是準備進一步與 R 語言做比較。
關於入門?
相比較而言,matlab 提供了充足的幫助文檔和各類官方資料,特別是中文網頁的幫助都較為完善,而 CRAN 其實並沒有完整的中文幫助 。
尤其是在幫助文檔方面,matlab 相較於 R,更加清晰明了,整體較為規範統一。在 R 的各個函數的幫助信息上,除了基礎函數以外,其他的包中的函數都是由各個作者來編寫的,因此每個人有自己的特色,在示例代碼及註解上風格不盡相同。
R 語言目前仍缺乏完善的中文說明文檔,但這並不現實,開源社區提供的貢獻已經夠多了。雖然說中文內容不夠完善,但這並不影響 R 語言的用戶。畢竟 R 並不給用戶承擔任何責任,出錯,只能由用戶來擔責。而 matlab 的服務則是建立在用戶付費的基礎之上。你沒有付費,又哪來的享受到官方提供的維護服務 。
關於入門周期,matlab 要短於 R ; 入門難度上, matlab 要比 R 簡單 ;新手遇到的問題的多少,matlab 用戶小於 R 用戶 。入門所需的知識體系上,matlab 教學已經形成了完善的體系, 在目前國內高效的教學上,這一點顯而易見。
但論入門之後的難易程度而言,R 的代碼量要比 matlab 小一些,並且不需要在很多的細節上注意很多,代碼較為簡便、易讀。
matlab 有兩種語法:函數和命令,很多時候,函數有著起相同功能的命令,而命令是命令名稱+空格+參數的形式來呈現,函數則需要後面跟著括號,括號內部的參數用逗號分隔。
而 R 語言本質上,就是在調用函數來使用,並沒有命令的概念。需要提醒的是關於系統命令的調用,需要使用 system() 函數。
關於幫助類函數:
R 語言的幫助類函數可以參考之前的參考卡片中的 A. 的內容,詳情見 R參考卡片
而 matlab 中最主要的幫助類函數還是 help ,所不同的是它沒有 ?來使用。
lookfor keyword 命令則類似於 R 的 help.search() 函數。它和 apropos() 根據關鍵詞檢索顯示所有的函數名列表還是不太一樣的。
matlab 的 doc 命令,則與 R 的 help() 較為相似。相比較之下 doc 函數名 提供的幫助信息,更接近於 R 的help() 或 ?的幫助信息內容。
總結:matlab 則更多地使用 doc 命令來查詢幫助文檔,而 R 則通過 help() 或 ?來查詢幫助文檔。
關於詳細的 matlab vs R, 可以參考 CRAN 上的文檔:
https://cran.r-project.org/doc/contrib/Hiebeler-matlabR.pdfwho 命令等同於 R 的 ls() 函數,但你需要注意的是 ls() 還有一個別名函數:objects(); whos 命令顯示變量名和詳細的附屬信息,這一點和 ls.str() 的功能相似。
接下來,我們需要談及 clear 命令
clear rm() 或 remove() clear x y z rm(x,y,z) clear all rm(list = ls())matlab 的命令意味著你必須用空格來分隔多個變量名,當然,命令是 matlab 的一大特色,它繼承了傳統命令窗口下的眾多命令名稱,在一次性清除所有變量上,比 R的函數要簡便不少,但這不利於統一性的使用。
最大的不同在於賦值問題:
matlab R x = 5:10 x <- 5:10matlab 採用等號完成賦值操作,雖然 R 語言支持使用等號完成賦值,但遵循 R 的傳統以及大多數用戶的習慣,我們仍然以 <- 作為變量賦值使用,而等號用於參數的賦值以及創建數據框過程中。當然,R 中還有一堆的賦值符號:
a <- b <- c <- 5 <- -> ->> <<- 甚至,我們也可以實現連續賦值操作。
ans 指的是matlab 已運行的代碼中最後一個未賦給變量名的值,這個值被賦予 ans 名稱。而 R 中 .Last.value 指的是最後一個值,不論它是否具有變量名。
符號 matlab R ;用於該行代碼不輸出結果,
用於數組中行之間的分隔
用於兩個函數或語句位於同一行時的分隔 ,用於兩個函數或命令之間的分隔,但輸出結果並顯示;
用於變量之間的分隔;
用於數組中元素的的分隔
用於元素之間的分隔;
用於函數中參數之間的分隔
注釋符號 % # 塊注釋%{
%}
沒有,
但可以採取
if (F) {
}
相比較而言,matlab 必須使用分號來抑制輸出,這就顯得比較麻煩。而 R 的分號則極少被用到。。。
R 語言並沒有塊注釋的功能,if(F) { }的形式來達到塊注釋的效果
R 語言的基本數據類型,可以從上面的內容中看出,最核心、最重要的還是 c() 函數,其次是 data.frame()
matlab Rx = [1, 3, 5, 9]
x = [1; 3; 5; 9]
x <- c(1,3,5,9) x = 1:9x <- 1:9x = 1:2:9 x <- seq(1,9,2) x = 9:-2:1x <- seq(9,1,-2) linspace(1,20,6)seq(1,20,length.out = 6)
seq(1,20,len = 6)
關於 rep(), 用於生成重複序列的向量。matlab 暫時還沒有很明確的函數可以與之對應。
類型 matlabR 數值int8 uint8
int16 uint16
int32 uint32
int64 uint64
single double
double(),
numeric(),
integer(),
c(), vector()
rep(), seq()
邏輯值 logical T,F, TRUE, FALSE 字符串char
string
character()
c()
stringr包
矩陣 [] matrix()時間日期datetime
duration
calendarDuration
as.Date()
as.POSIXct()
lubridate 包
表格型數據 table data.frame()
tibble() #tibble 包
總而言之,matlab 中皆為數組,不論是行向量、列向量,還是字符、字符串,甚至是時間,它都是數組的特殊形式。而 R 奠定了以向量為基礎的數據形式。比較有意思的是,matlab 推出了表的數據類型,它與 R 的數據框有著高度的類似性:
matlabR readtable read.table()writetablewrite.table()head
tail
head()
tail()
istable is.data.frame() summary summary()接下來,需要談及 is 系列函數,用於判斷是否為某一類型的數據
matlabR isnumeric is.numeric()isobject is.object()isinteger is.integer() isfloatis.double()ischar
isstring
is.character() islogical is.logical()isrealis.complex()isgraphics is.ggplot2()istable is.data.frame()內容 matlab R 轉為字符串char
int2str
num2str
as.character() 十進位與十六進位轉化dec2hex
hex2dec
dec2hex;
hex2num, num2hex
as.hexmode()
unclass()
as.numeric()
十進位與八進位轉換base2dec('strn', base)
bin2dec
設置參數為 8
as.octmode()
unclass()
as.numeric()
N 進位轉為十進位 base2dec strtoi('13',16) # 16進位的'13' 轉為十進位二進位轉為十進位數字bin2dec
strtoi('1101', 2) 十進位轉為二進位 dec2binR.utils::intToBin(13)
需要加載 R.utils包,使用其中的 intToBin() 函數
字符轉 Unicodedouble('ABCDabcd')
abs('ABCDabcd')
charToRaw('ABCDabcd')
Unicode 的前 128 個字符與 ASCII 碼相同,因此不再重複說明,值得注意的是,chartoRaw() 是把字符轉為 raw 類,但基本的字母轉出的數字與 Unicode 相同,這裡暫時將其與 matlab 中的轉換做對比。R 語言並不支持直接將字符轉為數字,在這一塊上,並不如 matlab 的功能豐富,以上涉及到轉為其他進位字符的方法在 R 語言的實際使用中並不多見,這些,更多的是 C 語言一類的初學階段需要掌握的知識點。只是 R 並不側重於這些的使用。。。matlab R zeros(1,5)numeric(10)
integer(10)
double(10)
ones(1,5) rep(1,5) eye(5) diag(5)matlab 通過 zeros(1,5) 來生成行向量,其值全為零。而 R 沒有行向量與列向量的區分,本質上仍然是向量。雖然 R 提供了 integer(), double() 函數,但在實際使用上,並不過多強調數據分為整型、浮點數等,也不區分單精度、雙精度問題。
matlab R x1 = 1:5
x2 = 7:10
[x1, x2]
x1 <- 1:5
x2 <- 7:10
c(x1,x2)
x1 = 1:5
x2 = 6:10
[x1; x2]
x1 <- 1:5
x2 <- 6:10
rbind(x1,x2)
按行合併,matlab 的操作等同於 rbind(),但兩者均要求向量的大小需相同,否則不能合併。同時 R 的 cbind() 列合併暫時沒有可以與之直接對應的語句。
matlab R x1 = reshape(1:5,5,1)
x2 = reshape(6:10,5,1)
[x1 x2] 或 [x1, x2]
x1 <- 1:5 或 x1 <- matrix(1:5)
x2 <- 6:10 或 x2 <- matrix(6:10)
cbind(x1,x2)
在這裡,需要將 matlab 中的行向量轉為列向量,接著合併即可,此時就等同於 R 語言中的 cbind() 函數。
當然,你可以選擇使用 x(:) 的方式來獲得列向量,前提是 x 是一個變量,但在這裡,直接使用 reshape() 會更加便捷一些。
可以將 matlab 的行向量與列向量與 R 的向量等同,其他部分則需要與 矩陣、數組做比較,這裡不再過多闡述。
matlab R reshape(1:5,5,1)x <- matrix(1:5)
dim(x) <- c(5,1)
x
matlab 的程序文件分為腳本文件和函數文件,你可以在命令行窗口直接鍵入腳本文件名便可以運行整個文件,得到輸出結果,但 R 並不能這樣做,它需要 source() 函數運行,其中的參數為完整的文件名 + 後綴名。
matlabR .m .R .mat.Rdata
.rds
.m 文件和 .R 文件較為類似,都是保存代碼的文件,但 R 語言並不區分腳本文件和函數文件。
.mat 是 matlab 的數據儲存文件,依靠 load 和 save 命令來實現數據加載和保存。同樣地,R 語言相對較為複雜一些。.RData 則可以保存多個對象信息,而 .rds 只用於保存單個對象,因此 save() 和 load() 的用法與 matlab 相一致。
而如果想要保存整個工作區的所有變量時,就需要使用 save.image() 函數。同時對於 .rds 文件,就需要 saveRDS() 和 readRDS() 函數來搭配使用。
但事實上,很多 R 語言的教程以及視頻講解,都不怎麼涉及數據的保存以及腳本文件運行的詳細說明,在這一點上,matlab 教學要強於 R.
1,輸入原始數據,有注釋部分
2,主體部分,進行處理
3,輸出結果部分
函數編寫
matlab 的函數編寫,涉及到三種方法:函數文件,inline函數,匿名函數,它的一大特色在於:
function [output1, output2,...] = functionname(input1,input2,...)包括函數調用時,也可以由函數傳遞給多個輸出值,這是 R 所不能比擬的。R 的函數,你可以通過 print() 等實現輸出多個信息,但不能實現函數輸出結果賦給多個對象。對於不同類型對象的一同輸出,通常可以將其寫入 list 中,輸出為一個list 對象。
在 if語句,for語句,while語句上,並沒有太大的區別。但 matlab 需要有 end 語句,R 語言則沒有 end; 同時對於 ifelse, 二者採取了不同的方式來表達。二者在 break 和 return 語句上較為相似。總之,比較下來,R 對於函數編寫的要求較低,並沒有 matlab 那般嚴格。
而對於匿名函數,R 本身並不具備,而是在 tidyverse 模式下提供了匿名函數的用法。這一點需要引起注意。
運算操作
運算操作 matlab R 加減乘除 .+, .-, .*, ./+,-*,/ a^b a^b, a**b sqrt(a) sqrt(a) exp(a) exp(a)整除 idivide() a %/% b 餘除rem(a,b); mod(a,b)a %% b log(a) log(a) 矩陣乘法 * %*% log2(a) log2(a) log10(a) log10(a) abs(a) abs(a)轉置 x.' t(x) 判斷正負 sign(x)sign(x)最大值
最小值
max(x)
min(x)
max(x)
max(x)
平均值
中值
mean(x)
median(x)
mean(x)
median
長度 length(x)length(x)求和 sum(x)sum(x)階乘 factorial(n)factorial(n)這裡面,大部分的函數都是相同的名稱,因此並不太大區別。需要注意的是轉置操作、整除、餘除有所不同,另外關於矩陣的乘法也有所區別。特別需要注意的是 R 是針對向量進行四則運算,它等同於 matlab 裡的點運算。
接下來,將分類別比較各類計算相關的函數。
matlab R排序
(默認升序)
sort(x) sort(x)顛倒元素 flip(x)rev(x)關於三角函數:
內容matlabR 三角函數sin()
cos()
tan()
atan2(y,x)
sin()
cos()
tan()
atan2(y,x)
反三角函數asin()
acos()
atan()
asin()
acos()
atan()
雙曲函數sinh()
cosh()
tanh()
sinh()cosh()
tanh()
反雙曲函數asinh()
acosh()
atanh()
asinh()
acosh()
atanh()
度數或 為單位sind()
cosd()
tand()
....
僅有:
sinpi()
cospi()
tanpi()
matlab 的三角函數中還具有 sec(), csc(), cot() 等,但 R 並不具有,因此這些函數,假若你真的需要在 R 裡使用,自己造出來函數即可。這其實不存在任何問題。同樣地,matlab 中的 sind() 一類的函數,支持以度數輸入,但 R 並不支持,R 的輸出要求的是 pi 一類的數值,加入需要類似的輸出,自己造一個 sind() 即可。
sind <- function(x) sin( x/ 180 * pi) sind(30)因為:
所以類似地,你可以很容易地就自己造出來那些沒有的函數,所以這些問題都不是大問題。
取整運算
matlabR round() round()floor() floor()ceil() ceiling() fix()trunc()取整運算,基本相同,需要注意的是向零取整,兩個函數名並不一致。但 ceil 區別並不大。
matlabR union(x,y)union(x,y) intersect(x,y) intersect(x,y)setdiff(x,y) setdiff(x,y) unique(x,y) unique(x,y)集合運算上,二者基本上沒有差別。
matlab R complex()
complex()
as.complex()
i,j ireal()Re()#實部 imag() Im() #虛部 abs() Mod(x) #模 angle() Arg(x) 複數角度 conj()Conj(x) # 共軛複數最大的不同在於 R 語言只識別 i 作為複數單位,沒有像 matlab 提供了兩種複數單位。
matlabR ans .Last.valuei,j i inf Inf, -Inf NaN NaNpipieps.Machine$double.eps
兩者均為 2.22e-16
realmax .Machine$double.xmax realmin.Machine$double.xminintmax.Machine$integer.max# R language > .Machine$double.eps [1] 0.00000000000000022204460492503131 > .Machine$double.xmax [1] 1.7976931348623157e+308 > .Machine$double.xmin [1] 2.2250738585072014e-308 # matlab >> eps 2.2204e-16 >> realmax 1.7977e+308 >> realmin 2.2251e-308值得注意的是,R 語言其實很多教程中並沒有說明該從哪裡查找 eps, max, min 值的方法,很多時候也並不強調計算精度的相關問題。
在 eps, realmax, realmin 上,R 和 matlab 是保持一致的。
但 R 在使用過程中還是需要注意以下問題:
> ab <- 123456789012345678901234567890 > format(ab,scientific=F) [1] "123456789012345677880204040666" > getOption('scipen') [1] 0 > options(scipen = 0); ab [1] 1.2345678901234568e+29 > options(scipen = 50); ab [1] 123456789012345677880204040666 > ac <- 0.01234567890123456789012345678 > ac [1] 0.012345678901234568 > options(digits = 22) > ac [1] 0.012345678901234568R 語言在顯示較大的數字時,到第 16 位之後,無法正確顯示,後面位數儲存的並不是原來的數字信息,即便是使用 format() 函數關閉科學計數法選項,也無法正確顯示後面的位數內容。而在儲存一個接近於零的數字時,在16位之後也不再顯示,即使更改 options(digits = 22) 位數變更為最大值 22, 也不再顯示過多的位數,這一點需要引起重視。
而 R 語言提供的其他常量則如下所示:
運算符:
R 語言的運算符在這裡作比較的是以上幾種。與 matlab 表示有區別的,在於 非 和 不等於。
matlabR doc 運算符優先級 ?Syntax< > <= >=
==
<> <= >=
==
~= != ~ !&
&&
&
&&
|
||
|
||
xor(x,y) xor(x,y)matlab 同時也提供了 and(), or(), not() 函數,R語言目前沒有這樣的函數,需要引起重視,但 xor() 函數,兩者都具有。
matlab R all()all() any()any()find() which()matlab() 的 find() 函數等同於 R 的 which()
在這裡,也要重新提及 which 相關的一系列函數。(先規定 x 為向量,A 為矩陣,便於區分不同的對象,將 matlab 的行向量、列向量看作與 R 的向量相同的效果)
matlabRx <- 1:5;
max(x)
x <- 1:5
max(x)
[a b] = max(x) max(x); which.max(x)max(x,y) pmax(x,y)max(A)
% 每一列的最大值
apply(A,2,max)
sapply(A,2, max)
%每一行的最大值
max(A,[], 2)
apply(A,1,max)
sapply(A,1,max)
x = [7,18,4,3,2]
[a,b] = sort(x)
x <- c(7,18,4,3,2);x
sort(x); order(x)
prod() prod()cumsum() cumsum()sumprod()cumprod()summax();
summin()
summax()
summin()
關於索引值的返回,matlab 用一個函數的兩種調用方式來解決索引值的返回問題,這看起來很節省,但並不是那麼容易使用。而 R 則進一步把函數劃分開來,利用 order() 解決索引輸出,將 極值函數進一步細分為 max(), pmax(), which.max() 等
%matlab >> x= [7,18,4,3,2]; >> [a,b] = sort(x) a = 2 3 4 7 18 b = 5 4 3 1 2 #R > x <- c(7,18,4,3,2);x [1] 7 18 4 3 2 > order(x) [1] 5 4 3 1 2 > sort(x) [1] 2 3 4 7 18到這裡的話,大部分的運算操作已經做了比較。剩下的主要是數值計算和符號計算的比較。R 語言同樣支持符號計算,但和 matlab 還是有一些不同之處,需要在下次集中展示它們之間的區別,另一些則是比較碎的知識點,比如:
點乘和叉乘的計算
和 的計算
計算內容 matlabR dot(x,y)sum(x*y)
x %*% y
crossprod(x,y)
cross(x,y)library(RSEIS)
xprod(x,y)
R 語言並沒有直接具備這兩個運算的函數,因此需要額外想辦法來計算。
#R > x <- c(1,2,3) > y <- c(2,3,4) > x %*% y [,1] [1,] 20 > sum(x*y) [1] 20 > crossprod(x,y) [,1] [1,] 20 > xprod(x,y) [1] -1 2 -1x = [1,2,3]; y= [2,3,4]; dot(x,y) cross(x,y) ans = 20 ans = -1 2 -1 matlabRprctile(x,p)
'prctile' 需要 Statistics and Machine Learning Toolbox
fivenum()
quantile()
matlab R var() var()std() sd()size() dim() cov() cov()corr()cor()diff()diff()mean(x)
mean(A,2)
mean(A,1)
mean(x)
rowMeans()
colMeans()
sum(x)
sum(A,1)
sum(A,2)
sum(x)
colSums(A)
rowSums(A)
隨機抽樣
'randsample' 需要 Statistics and Machine Learning Toolbox
randsample(n,k,true,...)
sample(x,size,replace =TRUE,...)
replace = T 時,有放回地抽樣
內容matlabR 隨機數種子 set.seed(n)組合數
nchoosek(n,k)choose(n,k)
choose(x,k)
排列數
factional(n)/factional(n-m)choose(n,k) * factorial(k)組合數顯示 nchoosek(1:n,k)combn(n,k)
combn(x,k)
combn(n,k) %>% t()
#R > choose(5,2) [1] 10 > choose(1:5,2) [1] 0 1 3 6 10 > combn(5,2) %>% t [,1] [,2] [1,] 1 2 [2,] 1 3 [3,] 1 4 [4,] 1 5 [5,] 2 3 [6,] 2 4 [7,] 2 5 [8,] 3 4 [9,] 3 5 [10,] 4 5%matlab >> nchoosek(5,2) ans = 10 >> nchoosek(1:5,2) ans = 1 2 1 3 1 4 1 5 2 3 2 4 2 5 3 4 3 5 4 5在組合數顯示上,matlab的 choose(v,k) 中 v 為向量,其返回值為矩陣,等同於 R 的 combn(n,k) 轉置後的結果。
文件及目錄
操作
matlabR 更改工作路徑 cd dirname setwd('dirname') 列出當前路徑下的文件dir
ls
dir()
list.files()
顯示工作路徑 pwd getwd()連接路徑fullfile() file.path() 文件是否存在 exist()file.exists()返回當前路徑下文件的完整路徑名 which filename normalizePath('filename.後綴名')建立新的目錄 mkdir dir.create() 刪除目錄 rmdir unlink('dirname',T) 刪除文件 deletefile.remove()移動文件 movefile 文件複製 copyfile file.copy() 編輯或創建文件edit m
file.edit('m.R')
打開文件 fopen(filename,permission)file(description = "", open = "",...)
open(con, open = "r",...)
關閉文件 fclose()close(con,open = )讀取,寫入文件fread(); fscanf()
fwrite(); fprintf()
textscan()
cat(); scan()
write();print(); sink()
readLines(); writeLines()
readBin(); writeBin()
tablereadtable()
writetable
read.table()
write.table()
csvcsvread()
csvwrite()
read.csv()
write.csv()
excel 文件xlsread()
xlswrite()
readxl包 的 read_excel() 等等
xlsx 包
粘貼板相關 clipboard() 'clipboard' 在 R 中可以視作一個文件。 當然,R 裡面還有 read.delim() 和 read.fwf() 以及 readr 包、rio 包、data.table 包的 fread() 函數 等等。對於大文件的讀取,則不建議採用基礎函數。
接下來的部分,可能涉及到:數值計算,符號計算,基礎繪圖函數比較,統計計算相關,還有 ggplot2 類似繪圖的比較。 這些會在以後逐步展開討論。需要說明的是 R 肯定也能做符號計算。在繪圖方面,如果是偏工程領域以及三維繪圖,相對而言,matlab 可能更好一些。另外在交互繪圖方面,R 會稍差一些。但目前 R 語言繪圖,已經形成了以 ggplot2 為主流的趨勢,這一點毫無疑問已經是最重要的學習方面,ggplot2 繪圖的生態也在一步步地提高、完善。二者各有各的方向和用戶群體,沒必要非要評個誰比誰強。R 語言轉向學習 matlab 的話,一上來比較麻煩的點主要有:1,命令和函數共存,共同使用的煩人局面;
2,得遵循 int8 int16 double 等一系列的數據格式,以及數組計算的難懂模式。。。
3,toolbox 安裝很龐大,不如 R 的包靈活、輕巧。
4,卸載,重裝的麻煩局面,不如 R語言配置環境來的順手。
5,繪圖函數,就像 R 語言的基礎繪圖模式一樣,記憶的量太大,不如 ggplot2 繪圖的函數系統化。
6,gui 設計,就有點類似於 R 的 shiny, 但兩者要想精通,都是非一朝一夕之功。
7,函數文件,命令文件,以及腳本運行,都沒有 R 顯得那麼隨和,輕鬆。編寫函數,也比 R 複雜一些。
8,統計計算相關,沒有 R 來的容易。
9,要學習的程式語言相關的學院派的知識太多,沒有 R 語言那般注重使用性。
10,R 支持向量化操作,側重批量計算、處理。matlab 還是建議側重 for 循環一類的結構,以及矩陣計算。
11,matlab 一年兩次版本升級,R 的更新主要是包的更新,相比之下,R 的更新更快速、更頻繁一些。