讀《R語言編程藝術》

如果說R語言學習者會有的書,大概率會有這一本。本書可以說是R語言學習者和使用者的一個分水嶺,在此之前是各種copy調試,在此之後開始用R做一些自己的事情。其實這樣的書可以羅列出好幾本:

  • ggplot2 數據分析與圖形藝術(ggplot2 Elegant Graphics for Data Analysis)
  • R語言實戰(RinAction)
  • R語言核心技術手冊(RinaNutshell)
  • R語言數據科學(R for data science)
  • 高級R語言編程指南( Advanced R)

這些書每看完一本,都會對R的特性有進一步的理解。《R語言編程藝術》這本書是買的比較早的了,之前也泛泛地翻過,主要是對R的特點有個相對系統的理解。從目錄導圖中不難看出,這本書涉及的內容是廣泛的,如果恰逢其時,你會覺得這本書就是爲當下的你寫的——就像第九十八個階梯,早一步的話望而卻步,晚一步的話只只剩下驀然回首。所以這是一本時長拿來看看的R語言書籍:說不定哪一次就對上號了。

本書的特點主要有:

  • 系統知識
  • 實例講解
  • 擴展案例
  • 第七章是這本書的核心

最主要的特點是有大量的演示案例,雖然大部分的主題在 R語言數據科學 或者R語言核心技術手冊均有涉及,但是講述的方法不同,往往樂意無窮《R語言數據科學》這本書像是哈德利·威克漢姆用自己定義的R語言在講述這些知識點(哈德利·威克漢姆重新定義了很多),R語言核心技術手冊又顯得太厚了,讓人向面對 R語言實戰 一樣,望而卻步。

我覺得第七章<R語言編程結構>是這本書的核心,這也許和目前我的水平有關:開始關注函數的實現與組織。這一章探討了編程中的控制結構以及函數的實現,環境作用域等,函數編程的基本概念。在這一章中,我們可以體會到用R語言和會編程其實是兩件事。

像編程這樣的書籍,讀一遍是遠不夠的,因爲我們系要理解的不是人類語言的部分,而是非人的代碼部分,不僅要理解更是要能運用。這也是做紙質書的好處,可以在代碼上做註釋,寫下自己的驚歎和感悟。

另外,本書值得學習的是關於debug的部分,在做調包俠的時候很少用到這項技能,遇到問題找R包換R包安R包,但是如果是自己寫函數了,或者有的R包還不太成熟的話,就需要我們來爲代碼debug。這部分內容,對很多已經是調包俠的人來說是一個進階的突破口。

# class "ut", compact storage of upper-triangular matrices

# utility function, returns 1+...+i
sum1toi <- function(i) return(i*(i+1)/2)

# create an object of class "ut" from the full matrix inmat (0s included)
ut <- function(inmat) {
    n <- nrow(inmat)
    rtrn <- list()  # start to build the object  
    class(rtrn) <- "ut"
    rtrn$mat <- vector(length=sum1toi(n))  
    rtrn$ix <- sum1toi(0:(n-1)) + 1  
    
    for (i in 1:n) {  
        # store column i
        ixi <- rtrn$ix[i]
        rtrn$mat[ixi:(ixi+i-1)] <- inmat[1:i,i]
    }
    return(rtrn)
}

# uncompress utmat to a full matrix
expandut <- function(utmat) {
    n <- length(utmat$ix)  # numbers of rows and cols of matrix
    fullmat <- matrix(nrow=n,ncol=n)
    for (j in 1:n) {
        # fill j-th column
        start <- utmat$ix[j]  
        fin <- start + j - 1 
        abovediagj <- utmat$mat[start:fin] # above-diag part of col j
        fullmat[,j] <- c(abovediagj,rep(0,n-j))  
    }
    return(fullmat)
}

# print matrix
print.ut <- function(utmat) 
    print(expandut(utmat))

# multiply one ut matrix by another, returning another ut instance;
# implement as a binary operation
"%mut%" <- function(utmat1,utmat2) {
    n <- length(utmat1$ix)  # numbers of rows and cols of matrix
    utprod <- ut(matrix(0,nrow=n,ncol=n))  
    for (i in 1:n) {  # compute col i of product
        # let a[j] and bj denote columns j of utmat1 and utmat2, respectively, 
        # so that, e.g. b2[1] means element 1 of colument 2 of utmat2 
        # then column i of product is equal to 
        #    bi[1]*a[1] + ... + bi[i]*a[i]
        # find index of start of column i in utmat2
        startbi <- utmat2$ix[i] 
        # initialize vector that will become bi[1]*a[1] + ... + bi[i]*a[i]
        prodcoli <- rep(0,i)
        for (j in 1:i) {  # find bi[j]*a[j], add to prodcoli  
            startaj <- utmat1$ix[j] 
            bielement <- utmat2$mat[startbi+j-1]
            prodcoli[1:j] <- prodcoli[1:j] + 
                bielement * utmat1$mat[startaj:(startaj+j-1)]
        }
        # now need to tack on the lower 0s
        startprodcoli <- sum1toi(i-1)+1
        utprod$mat[startbi:(startbi+i-1)] <- prodcoli
    }
    return(utprod)
}

test <- function() {
    utm1 <- ut(rbind(1:2,c(0,2)))
    utm2 <- ut(rbind(3:2,c(0,1)))
    utp <- utm1 %mut% utm2
    print(utm1)
    print(utm2)
    print(utp)
    utm1 <- ut(rbind(1:3,0:2,c(0,0,5)))
    utm2 <- ut(rbind(4:2,0:2,c(0,0,1)))
    utp <- utm1 %mut% utm2
    print(utm1)
    print(utm2)
    print(utp)
}

test()




https://github.com/cosname/art-r-translation

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