读《R语言编程艺术》

2021-10-12 15:37:54 浏览数 (1)

跟着运来兄搭建自己的生物信息小书房。趁年轻,读几本硬书,到老了慢慢反刍。

如果说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。这部分内容,对很多已经是调包侠的人来说是一个进阶的突破口。

代码语言:javascript复制
# 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

0 人点赞