S-Plus:若非向量,既为矩阵

Krause and Olson (2005:303) say:"An iteration is, in principle, a loop or an repeatedly executed instruction cycle, with only a f ew changes in each cycle. In programming languages that are not matrix- or array-oriented, even simple matrix multiplication needs three nested loops(over rows, columns, and the indices).Since S-Plus is matrix-oriented, these operations are much more efficient and easy to formulate in mathematical terms. This means they are typically substantially faster than loops and the code is much easier to read and write…….Whenever possible, try to avoid loops. Ninety-nine percent of the time, an operation on matrices or lists is much more elegant as well as much faster. Try to use vectorized statements and functions such as apply, lapply, rapply, sapply, tapply, by, split, and others."
我完全同意上述观点,但是第一次学习使用S-Pllus这种matrix-oriented的语言来写东西实在让我头大。以下是Krause and Olson (2005:318)中的一个小练习:
Exercise 9.4
Create a list with names,telephone numbers, and addresses of five of your friends. Write a function, tel, that gets passed a name and returns the appropriate address and telephone number. This function should handle the case of being passed a name that is not in the list.
以下是数据输入部分的书中标准答案。我的代码与之差异不大:
tel.data<-list()
tel.data[[1]]<-c("Paul","Tom","Bert","Peter")
tel.data[[2]]<-c("007","008","009","010")
tel.data[[3]]<-c("Boston","Seattle","Berlin","Zurich")
names(tel.data)<-c("name","tel","address")
接下来的函数tel的代码就差的十万八千里了,先贴出书中的标准代码,即matrix-oriented and avoiding loops:
telephone<-function(name)
{
    compare<-name==tel.data$name
    found<-any(compare)
    if(!found)
    {
     cat("Name not found.\n")
     return(invisible())
    }
    cat("Name:\t",tel.data$name[compare],"\n")
    cat("Telephone:\t",tel.data$telephone[compare],"\n")
    cat("Address:\t",tel.data$address[compare],"\n")
    return(invisible())
}
天知道S-Plus还有个internal的compare函数!所以我一上来就loop了:
telephone<-function(x)
{
    for (i in 1:length(L[[1]]))
    {
     inlist<-F
     if (x==L[[1]][i]) 
       {
           cat("Name: ", L[[1]][i],"\n")
           cat("Address: ", L[[2]][i],"\n")
           cat("Phone number: ",L[[3]][i],"\n")
           inlist<-T
        }
     if(inlist) break
    }
   if (inlist==F) warning("not found")
   else return(invisible())
}
两相比较,可以说是风马牛不相及。不习惯matrix-oriented的思维,郁闷中。

About Hongwei Xu

I'm a social demographer, a single-child, a husband, and a father.
This entry was posted in 未分类. Bookmark the permalink.

5 条 S-Plus:若非向量,既为矩阵 的回复

  1. Yin说道:

    我这学期搞了一学期的LISREL,和你这个异曲同工

  2. liao说道:

    profile里的pic怎么看怎么不像你啊

  3. Hongwei说道:

    我不太上镜,真人比照片的确帅很多

  4. lin说道:

    远看倒像是我,晕阿.还有,你们搞点俺能看懂的东西好不好?

发表评论

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / 更改 )

Twitter picture

You are commenting using your Twitter account. Log Out / 更改 )

Facebook photo

You are commenting using your Facebook account. Log Out / 更改 )

Google+ photo

You are commenting using your Google+ account. Log Out / 更改 )

Connecting to %s