小男孩‘自慰网亚洲一区二区,亚洲一级在线播放毛片,亚洲中文字幕av每天更新,黄aⅴ永久免费无码,91成人午夜在线精品,色网站免费在线观看,亚洲欧洲wwwww在线观看

分享

你知道R中的賦值符號箭頭(<-)和等號(=)的區(qū)別嗎?

 萌小芊 2018-04-10

作為一門高級語言,R語言擁有獨特的語法,比如今天說道的賦值符號。在其他語言里,賦值符合通常用一個等號(=)表示,而在R語言里,承擔這個任務(wù)的可以是箭頭(<-)符號,也可以是等號(=)。這就導(dǎo)致許多R語言初學(xué)者,分不清R語言中的賦值到底是使用箭頭(<-)還是等號(=)?許多早期學(xué)習(xí)R的童鞋都比較喜歡使用等號(=)進行賦值。畢竟,簡簡單單的a = 5用起來比較符合大多數(shù)現(xiàn)有語言的習(xí)慣。出于對某種賦值方式的偏好,甚至出現(xiàn)了等號黨和箭頭黨,但是到底孰好孰壞,顯然爭不出任何結(jié)果,相對來說更重要的是了解這兩者的區(qū)別。只有我們深刻理解了其相同與不同之后,才能更好的運用他們。

R語言最開始設(shè)計的時候,是采用箭頭(<-)作為賦值符號的,這是從APL語言繼承而來的(箭頭表示賦值,等號表示判斷)。之后的S語言也沿用了這個用法,再之后R語言為了保持和S語言的兼容性保留了這個箭頭。直到2001年,R的更新版本中 才加入了等號(=)賦值。因此,對于一般的賦值語句,箭頭(<-)與 等號(=)在 功能上是沒有區(qū)別的,可以通用。但是等號(=)的作用有兩個:它既可以賦值,也可以傳遞函數(shù)參數(shù)(實際上傳參可以看作一種特殊形式的賦值,給參數(shù)賦值)。通常情況下,如果等號(=)出現(xiàn)在單獨的環(huán)境中,它就是賦值;如果寫在函數(shù)的參數(shù)位置,它就是傳參。如果你在設(shè)置參數(shù)的時候使用了箭頭(<-),那么你會發(fā)現(xiàn)在全局變量里,會多出一個和參數(shù)名相同的賦值的變量,容易導(dǎo)致歧義和錯誤,而且占用命名空間。

下面,我們通過幾個個例子來具體講一下這兩個函數(shù)的區(qū)別。

  1. 箭頭(<-)和等號(=)賦值在作用域上的不同。
    箭頭(<-)創(chuàng)建的變量的作用范圍為整個全局環(huán)境(Global environment),而等號(=)通常在一個局部環(huán)境(Local environment)。例如:

    > rm(x)  ## 如果變量 x 存在的話,先刪除此變量 > mean(x = 1:10) [1] 5.5 > x Error: object 'x' not found

    在以上范例里,變量 x 是在函數(shù)的作用域里進行聲明的,所以它只存在于此函數(shù)中,一旦運算完成便“消失”。

    > mean(x <- 1:10) [1] 5.5 > x [1]  1  2  3  4  5  6  7  8  9 10

    而采用箭頭(<-)賦值,x 變量則出現(xiàn)在了Global Environment 里,并且我們可以調(diào)用它。 在此例中,實際上是先構(gòu)建了x變量,再將x傳遞給mean函數(shù)的第一個參數(shù),我們看到,采用這種方式,程序也正確運行了,但是采用箭頭(<-)賦值的方式去傳參時要非常小心??梢钥聪旅胬又幸疱e誤地情況。

  2. 箭頭(<-)和等號(=)在參數(shù)傳遞時的區(qū)別

    > x <- rnorm(100)  # 采用箭頭(<-)進行變量賦值 > y <- 2*x + rnorm(100)  # 采用箭頭(<-)進行變量賦值 > lm(formula=y~x) #上面的代碼完全等價于下面的代碼 > x = rnorm(100)  # 采用等號(=)進行變量賦值 > y = 2*x + rnorm(100)  # 采用等號(=)進行變量賦值 > lm(formula=y~x)

    兩段代碼中前兩行都是賦值語句,分別為x變量和y變量賦值,此時等號(=)與箭頭(<-)的功能相同,作用域也相同,因為等號(=)賦值是在全局環(huán)境中進行的,而代碼第三行中的等號(=)則是調(diào)用函數(shù)時規(guī)定命名參數(shù),這就是通常情況下,我們直接將y~x這個公式直接傳遞給lm函數(shù)的第一個參數(shù),也就是formula參數(shù)的用法。如果此時我們將等號(=)替換成箭頭(<-),則會在全局環(huán)境中定義出一個新的formula變量,然后再將這個變量傳遞給了lm函數(shù)的第一個參數(shù)。如果是我們有意這么做的話,就需要保證命名參數(shù)的順序和函數(shù)中定義參數(shù)的順序相同,否則就會出現(xiàn)錯誤,或者將名稱相同的變量傳遞給了錯誤的參數(shù)(但程序可能正常運行),導(dǎo)致結(jié)果錯誤。下面的例子可以突出了這種差別:

    > x <- rnorm(100) > y <- 2*x+rnorm(100) > z <- 3*x+rnorm(100) > data <- data.frame(z,x,y) > rm(x, y, z)    

    此時,環(huán)境中已經(jīng)沒有x,y,z變量,就只有變量data可以用來做z~x+y的線性回歸。標準寫法:

    > lm(formula=z~x+y,data = data) #也可以寫成如下形式: > lm(data=data,formula=z~x+y)

    當我們將等號(=)替換成箭頭(<-)時,正確的命名參數(shù)傳遞應(yīng)該按函數(shù)參數(shù)順序來逐個傳參:

    > lm(formula <- z~x+y, data <- data) Call:   lm(formula = formula <- z ~ x + y, data = data <- data) Coefficients:   (Intercept)            x            y   0.069869     3.062565     0.007503   > formula z ~ x + y

    運行也不會出錯,但是我們會發(fā)現(xiàn)函數(shù)實際上是調(diào)用的lm(formula = formula <- z ~ x + y, data = data <- data),這時產(chǎn)生了一個新的變量formula到環(huán)境中,并且在全局環(huán)境中就可以使用(實際上data變量也被更新了)。
    但是如果我們對lm函數(shù)的參數(shù)順序不了解或者由于馬虎搞錯了參數(shù)順序,這個時候就會容易出現(xiàn)錯誤。

    #錯誤的寫法:   > lm(data <- data,formula <- z~x+y)   Error in as.data.frame.default(data) :     cannot coerce class ''formula'' to a data.frame

    執(zhí)行時會報告異常,說明data被當作第一個參數(shù)formula傳遞,而formula被當作第二個參數(shù)data傳遞,而參數(shù)類型不匹配因而導(dǎo)致異常。因此,在函數(shù)的命名參數(shù)傳遞時,盡量不要用箭頭(<-),因為既會產(chǎn)生副作用(創(chuàng)建新變量),也無法利用命名參數(shù)傳遞的功能。上面的例子是程序提示了錯誤,但是有時候程序并不一定會提示錯誤,就很容易讓我們忽視結(jié)果實際上是錯誤的結(jié)果。例如:我們構(gòu)建矩陣時,

    # 構(gòu)建一個3列的矩陣 > matrix(c(1:12),ncol=3)  [,1] [,2] [,3] [1,]    1    5    9 [2,]    2    6   10 [3,]    3    7   11 [4,]    4    8   12 > matrix(c(1:12),ncol<-3)  [,1] [,2] [,3] [,4] [1,]    1    4    7   10 [2,]    2    5    8   11 [3,]    3    6    9   12

    我們可以看到,盡管兩種方法,都運行成功,且得到了一個矩陣,但是第二個結(jié)果是一個錯誤的結(jié)果,此處出錯的原因就是,ncol<-3是將3賦值給變量ncol,然后再傳遞給函數(shù)對應(yīng)位置的參數(shù),而在函數(shù)內(nèi)第二個參數(shù)實際上是對應(yīng)的nrow參數(shù)。在實際編寫代碼時,遇到這種情況,如果我們不注意,就會導(dǎo)致后續(xù)所有結(jié)果都出錯。

  3. 此外,還需要注意的一點就是,在傳參中采用箭頭(<-)進行賦值的變量只有在需要使用時才會改變其值。例如:

    > a <- 1 > f <- function(x) return(TRUE) > f(a <- a + 1); a [1] TRUE [1] 1

    請注意,以上范例里, a 的值并沒有改變,也就是a并沒有加1,還是原來的a值,這是在函數(shù)內(nèi)部并未用到參數(shù)a。這會導(dǎo)致程序里出現(xiàn)一些不可預(yù)期的結(jié)果并且降低代碼可讀性,所以不推薦在函數(shù)參數(shù)里使用箭頭(<-)這種賦值方式。在看下面的例子:

    > a <- 1 > f <- function(x) { +         if(runif(1)>0.5) TRUE +         else print(x) + } > f(a <- a+1);a [1] TRUE [1] 1 > f(a <- a+1);a [1] TRUE [1] 1 > f(a <- a+1);a [1] TRUE [1] 1 > f(a <- a+1);a [1] 2 [1] 2 > f(a <- a+1);a [1] TRUE [1] 2 > f(a <- a+1);a [1] 3 [1] 3

    上述代碼中,向函數(shù) f() 傳遞傳遞參數(shù) a <- a + 1 后,只有在隨機數(shù) runif(1) 小于0.5的時候,a 的值才會改變,即執(zhí)行+1操作,然后打印a。否則傳遞TRUE值。因此,因為隨機數(shù) runif(1) 的隨機性,每次調(diào)用函數(shù) f()后 a 的值是不確定的。

現(xiàn)在大家應(yīng)該清楚了解箭頭(<-)和等號(=)的區(qū)別了吧!個人建議,大家寫賦值語句時采用箭頭(<-),傳參時使用等號(=)。這也是大部分老師都會強烈推薦的用法。是因為使用箭頭(<-)賦值,意義清晰,可以保持代碼良好的可讀性,尤其是書寫復(fù)雜函數(shù)時,避免造成混亂。Google 的 R style guide(https://google./styleguide/Rguide.xml)也推薦使用箭頭(<-)賦值。 況且有些情況下,只能采用箭頭(<-)賦值,例如:system.time(c<-1:10)中就不能使用等號(=)。而從數(shù)學(xué)的角度來說,等號兩邊是相等的,即等號左邊的等于等號右邊的,等號右邊的也等于等號左邊的。等號本身并沒有指向性,因此并沒有辦法體現(xiàn)”賦值“這一含義。而在R中,箭頭(<-)符號生動的闡釋了賦值的含義,一個非等號(=)的賦值符從根本上向?qū)W習(xí)者暗示這樣一個真理: 賦值操作與數(shù)學(xué)上的等于是完全不同的。此外,箭頭(<-)符號可以雙向賦值,即x <- 10與10 -> x等價。習(xí)慣 <- 和 -> 的使用以后,也對后來習(xí)慣使用更為復(fù)雜的 <<- 以及 ->> 這兩個賦值符號(<<-或->>一般用于函數(shù)內(nèi)部,表示給上一層環(huán)境中的變量賦值)做好鋪墊,而 = 無法實現(xiàn)類似的功能。

另外也有等號黨提出異議,認為采用箭頭(<-)不如使用等號(=)。例如:如果我想判斷一個變量是否小于10,可以寫成 x<10;如果我想判斷一個變量是否小于-10,然后順手寫成x<-10,這時候就會產(chǎn)生歧義。關(guān)于處理負數(shù)時產(chǎn)生歧義的說法,只能說是沒有正確養(yǎng)成良好的空格習(xí)慣造成的,句號逗號后加空格,括號外圍加空格,運算符號兩邊加空格,這些應(yīng)該是學(xué)習(xí)代碼前就應(yīng)該懂得的常識。會犯出 a <- 5 和 a < -5 混淆的錯誤只能說明自己的代碼風(fēng)格糟糕,建議大家Google 的 R style guide(https://google./styleguide/Rguide.xml )中其他的一些代碼寫作規(guī)則。

Reference

  1. https://www.cnblogs.com/loca/p/4301344.html

  2. https://google./styleguide/Rguide.xml

  3. http://stat./R-manual/R-patched/library/base/html/assignOps.html

  4. https:///questions/1741820/what-are-the-differences-between-and-in-r

  5. http://bbs./thread-1247151-1-1.html

  6. https://cran./doc/manuals/R-lang.html#Argument-matching


    本站是提供個人知識管理的網(wǎng)絡(luò)存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點。請注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點擊一鍵舉報。
    轉(zhuǎn)藏 分享 獻花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多