Beta

It’s a beautiful thing when free data meets free algorithm.

前些天在准备中国第三届R语言会议(上海)的时候, 翻到以前记录在Google Notebook里的一些材料, 一篇是关于Google Codes关于R代码的规范,非常值得借鉴。

规范这个东西平时多多注意一些还是有好处的,就和作文一样,漂亮的字体总能有不错的加分。这里就不翻译原文了,摘一些 tips 供大家参考:

R风格规范

文件命名

以 .R 结尾的文件必须有实际意义,比如

GOOD: predict_ad_revenue.R 
BAD: foo.R

变量名和函数名

  • 变量名建议使用小写字母和dots,比如 variable.namevariableName 也是可以被接受的
  • 函数名起始字母为大写,不能包含dots,如 FunctionName

间隔和间距

  • 所有的二元运算符(=, +, -, <-, etc.)两端均需要有空格。
  • 不要在逗号前增加空格,但逗号后必须有一个

比如:

tab.prior <- table(df[df$days.from.opt < 0, "campaign.id"])
total <- sum(x[, 1])
total <- sum(x[1, ])
  • 在左括号前应增加空格,除了 function call 情况
1
2
3
4
5
# GOOD: 
if (debug)

# BAD:
if(debug)
  • 多余的空格是允许的,比如为了对齐增加可读性:

    plot(x = x.coord, y = data.mat[, MakeColName(metric, ptiles[1], "roiOpt")], ylim = ylim, xlab = "dates", ylab = metric, main = (paste(metric, " for 3 samples ", sep = "")))

大括号

左大括号不能独立成行,右大括号必须独立成行(除else情况),比如

if (is.null(ylim)) {
  ylim <- c(0, 0.06)
}

else情况的标准写法:

if (condition) {
  one or more lines
} else {
  one or more lines
}

行长度

不应超过80个字符

缩进

严格使用两个空格,不能使用 tabs

赋值

尽量使用 <-,而不要使用 =

一般性声明

如果我们遵循一致的声明,对代码的阅读和理解会更快更准确。这里包含

1. Copyright statement comment
2. Author comment
3. File description comment, including purpose of program, inputs, and outputs
4. source() and library() statements
5. Function definitions
6. Executed statements, if applicable (e.g., print, plot)

注释

  • 一定要注意在代码间增加你的注释。长注释以 # 开始,后跟一个空格
  • 短注释发生在代码后,两个空格间隔,# 开始,后跟一个空格
1
2
3
4
5
6
# Create histogram of frequency of campaigns by pct budget spent.
hist(df$pct.spent,
breaks = "scott", # method for choosing number of buckets
main = "Histogram: fraction budget spent by campaignid",
xlab = "Fraction of budget spent",
ylab = "Frequency (count of campaignids)")

函数定义

  • 函数的定义,优先无默认参数值的参数,有参数值的参数在后。
  • 每行一个参数是允许的,但有参数值的赋值不能断开。
1
2
3
4
5
6
# GOOD:
PredictCTR <- function(query, property, num.days,
show.plot = TRUE)
# BAD:
PredictCTR <- function(query, property, num.days, show.plot =
TRUE)

函数文档

  • 函数在定义完成之后需要紧跟注释内容
  • 注释内容包含一句话对函数的描述,每个参数(arguments)的描述,用 Args 表示;以及返回值的描述,用 Returns 表示。
  • 注释必须非常清楚,调用者可以不用读后续任何代码就可直接调用。

示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
CalculateSampleCovariance <- function(x, y, verbose = TRUE) {
# Computes the sample covariance between two vectors.
#
# Args:
# x: One of two vectors whose sample covariance is to be calculated.
# y: The other vector. x and y must have the same length, greater than one,
# with no missing values.
# verbose: If TRUE, prints sample covariance; if not, not. Default is TRUE.
#
# Returns:
# The sample covariance between x and y.
n <- length(x)
# Error handling
if (n <= 1 || n != length(y)) {
stop("Arguments x and y have different lengths: ",
length(x), " and ", length(y), ".")
}
if (TRUE %in% is.na(x) || TRUE %in% is.na(y)) {
stop(" Arguments x and y must not have missing values.")
}
covariance <- var(x, y)
if (verbose)
cat("Covariance = ", round(covariance, 4), ".\n", sep = "")
return(covariance)
}

TODO注释

用于指明临时代码、短期解决方案或足够好但还不够完美的地方。username处写的是了解该问题详细情况的人的名字,并不是指实际解决该问题的人。因此,当你建立一个TODO时,写上你自己的名字就可以了。 例如:

1
# TODO(liusizhe): Remove this code after the NewService has been checked in.

R语言规范

attach

避免使用它

对象和方法

  • 在S语言体系下有两套对象的定义,S3和S4,且都可以在R中使用。
  • S3体系的方法更加灵活、交互性更好,S4更加正式和严格。两套体系方法可以参考这里
  • 尽量使用S3体系,除非有足够的理由使用S4
  • 绝对要避免混合使用 S3 和 S4 的情况

声明1:估计这篇博文的受众会很少很少……

声明2:请将下载的漫画于24小时内删除,balabala……

话说到,为了保护我已经不太好的视力,前几天购置了一台Kindle DX,用来阅读电脑上大量存在电脑中的的pdf格式电子书。这个东东确实比较强悍,除了对这些pdf文字书籍支持比较不错外(当然有些书籍需要进行一些处理),对pdf格式的漫画支持更赞。

而我是一个彻底的漫粉,闲暇之余,从网上下载jpg格式的漫画(推荐下载工具ComicAiII),悠然自得看漫画,实在惬意的很~~

不过,有些下载的漫画有些问题,比如下面的这种的:

如果直接合并为pdf在Kindle DX上阅读,纵向显示的话,上下各有很大一块白边,画面非常小;

如果横向显示,效果更差,底部有一部分不能显示。想看完两页漫画的话,需要向上下翻页反复操作:

琢磨来琢磨去,还是得手动把漫画裁剪为适合Kindle阅读的大小(Kindle DX的标准9英寸屏显示区域和32开纸大小接近),并且把裁剪后的漫画顺序调换(日本漫画的阅读习惯是从左向右)。

说白了需要对每页jpg漫画做两件事:
  • 从中间分割,将一张jpg图片变为两张;
  • 为左右两张子图的增加顺序标记。

如果将分割的两张图片,右边图增加_0,左边图增加_1,即可满足要求。拿上面的086.jpg举例:170页(即右边部分)会被命名为086_0.jpg,171页会被命名为086_1.jpg,由于有了0、1标记,这样所有更新过的jpg合并为pdf文件的话,即可保证顺序的正确。

这一过程使用ImageMagickR来实现(Windows XP平台):

假如你的火影忍者的目录为D:/漫画/Naruto04,文件为001.jpg、002.jpg……,

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
setwd("D:/漫画/Naruto04")
dd <- dir()
ff <- function(x){
convert &lt;- paste("convert " , x ,
" -crop 2x1@ +repage +adjoin ",
"%d_",substr(x,1,3),".jpg",sep = '')
shell(convert)
reverse0 &lt;- paste("convert " , "0_", x ,
" ", substr(x,1,3), "_1.jpg", sep = '')
reverse1 &lt;- paste("convert " , "1_", x ,
" ", substr(x,1,3), "_0.jpg", sep = '')
shell(reverse0)
shell(reverse1)
shell(paste("del " ,"0_", x , sep = ''))
shell(paste("del " ,"1_", x , sep = ''))
shell(paste("del " , x , sep = ''))
}

for (j in dd) ff(j)
shell(paste('convert *.jpg ', '1.pdf',sep = ''))

注意:目标文件夹的所有文件将被替换!

最后要强调的是,虽然 Kindle 没有辐射,和一般的纸质书区别不大,但看多了仍然有损视力 ^_^

上周末一时无聊,跟朋友跑去看房子。回来总结一下,当作经验和大家分享一下。现在这年代,看房子主角向来都是职业顾问(俗称中介),跟中介打交道,斗智斗勇那是相当有意思!回想起来,看房子的过程,几乎可以说是一部部大片的集合!且请听我细细道来:

看房子的地带有些远,通州九棵树附近(北京除了五棵松以外,还有九棵树,囧)

因为不是自己买房子,所以心态比较随意。等我睡饱爬起,吃过早饭,收拾妥当已然11点有余。慢条斯理的奔向长椿街,记录了一下从长椿街到九棵树的地铁运行时间,差不多1小时。出轻轨,打黑车,果然被黑之,忍之……

奔向朋友看中的房子,留意了一下小区的环境——环境确实非常不错,低密度6层板楼,让人很放松的感觉。房主是个搞艺术的,内部装修非常有品位,当听到中介MM说物业费是每月0.9元时,我自己差点没忍不住,要出手。

警匪篇

我见到的第二波中介一行有5个,其中三个男的,各个满脸横肉,凶神恶煞一般,若不是说带我们去看房子,我还真把他们当成劫匪了。不过最让我纳闷的是,总共就我们3个看房的,来5个中介陪同,兴师动众。搞得卖房的业主开门时都愣了,明显提高了警觉(估计当时想的是不是抢劫)。

这段时间中介日子不好过,真热情啊~~

科技篇

第三波中介是店长加助理组合(一个中介店面会有3、4个店长),店长颇能侃,一边走一边胡扯,其实聊的和房子没点实际关系。更牛的是,最后一套房子也没给我们看,直接把我们忽悠到他店里了,现在想想也纳闷的很,怎么当时就听他的了。

最奇怪的是,进到他们的店里,我们3人的手机全没信号。本来,一路上不同的中介给我们通电话,突然手机没了信号,没有电话可接,相当不习惯。中介谈生意的手段非常高明:许诺我们中意的那套房子的业主30分钟必到,马上可以进入真刀真枪的划价阶段。然而30分钟过后……中介解释为:在路上,再等30分钟……又一个30分钟过去,中介解释:下班点,路上,有些堵(周日,囧),再等一刻钟……仍没到,解释:手机打不通了!不信你听听~~再等5分钟……演的真像,绝对不亚于我们敬爱的影帝爷爷。

就这样从4点半耗到了7点。事后我又看了看别人看房经历,发现中介店里都会有个房间可以屏蔽手机信号的,为什么把我们拉到店里,恐怕是不想让别的中介从抢走这单生意吧(高科技成就业务,真NB了)。

惊悚篇

第四波中介是两小伙儿,其中的一个文质彬彬,颇有好感。路上,聊到我们刚刚看的一套房子,中介告诉我们,那是小区里最便宜的一套。而后问我们,上一波的中介有没有告诉我们便宜的原因。当时我就冒疑问了,里面还有文章?

中介小伙儿说,你们没看到他们正对楼下的红垫子么?没觉得有问题?我心说了,估计可能要说屋里面有人去世之类的话题,不过也很正常么。但后来,中介小伙儿说的话还是让我打了个冷战:

“这楼下住了个老头,就一个人儿,有天直接挂在屋里了,但也没人知道。过了一个月,天气炎热,尸体腐烂,散发出恶臭才被邻居发现……后来医院过来人,整个楼都是福尔马林消毒水。上面的住户受不了,想快速出手……”

惊悚归惊悚,我其实是对着老头的子女是很有看法的。老头就一个人,不在身边照顾就罢了,电话也不勤着点打。真是林子大了,什么鸟都有。

后编

中介MM,中介GG都太牛了,坐在屋里谈费用的时候,手里只用一台20元的计算器完全搞定。嘴里还念叨着,这我们可以给你避税,这儿我们有优惠……

我还好事了一下,提议搞个Excel表,把房价输入,生成明细单,你我这边都省时间。结果被中介鄙视了一下,理由是周围政策环境变化是很快的,这东西只能装脑子里(言外之意,只能意会不能言传,额……)

据中介说,买房子有个费用叫“代书费”,是北京建委收的,收费的缘由是要求网签,而网签是由建委“代书”的,故要收这一笔。问题是,这笔费用不是常量,而是房价×0.5%,也是一笔不小的银子。我没忍住又好事了一把,搜了一下所谓的“代书费”,原来又是中介巧立名目。实际是“10元工本费和80元手续费”。

额,这中介也太无良了吧!

一则令人兴奋的简讯:

Oracle官方博客 最近更新的 New R Interface to Oracle Data Mining Available for Download,甲骨文开始正式支持R语言在Oracle数据库中的应用(简单的非官方说法是:甲骨文贡献了一个提供Oracle和R之间接口的附加包)。

援引博客中对R-ODM(R-Oracle Data Mining)的介绍:

R-ODM is especially useful for:

  1. Quick prototyping of vertical or domain-based applications where the Oracle Database supports the application
  2. Scripting of "production" data mining methodologies
  3. Customizing graphics of ODM data mining results (examples: classification, regression, anomaly detection)

众所周知,R在实现原型算法方面有着不可替代的巨大优势。诚然,通过R实现的一般性数据挖掘算法都可以嵌入到数据库中,但Oracle提供的这个接口,极大地提高了挖掘算法的部署效率。

今天(2010.06.08),CRAN上更新了RODM包的1.0-2版本,支持Windows、Linux、MacOS X系统。

下面是RODM包帮助文档中的一个例子,可以初步地体会算法高效的部署:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
## Not run:
x1 <- 2 * runif(200)
noise <- 3 * runif(200) - 1.5
y1 <- 2 + 2*x1 + x1*x1 + noise
dataset <- data.frame(x1, y1)
names(dataset) <- c("X1", "Y1")
RODM_create_dbms_table(DB, "dataset") # Push the training table to the database

glm <- RODM_create_glm_model(database = DB, # Create ODM GLM model
data_table_name = "dataset",
target_column_name = "Y1",
mining_function = "regression")

glm2 <- RODM_apply_model(database = DB, # Predict training data
data_table_name = "dataset",
model_name = "GLM_MODEL",
supplemental_cols = "X1")
windows(height=8, width=12)
plot(x1, y1, pch=20, col="blue")
points(x=glm2$model.apply.results[, "X1"],
glm2$model.apply.results[, "PREDICTION"], pch=20, col="red")
legend(0.5, 9, legend = c("actual", "GLM regression"), pch = c(20, 20),
col = c("blue", "red"),
pt.bg = c("blue", "red"), cex = 1.20, pt.cex=1.5, bty="n")

RODM_drop_model(DB, "GLM_MODEL") # Drop the model
RODM_drop_dbms_table(DB, "dataset") # Drop the database table
RODM_close_dbms_connection(DB)
RODM_close_dbms_connection(DB)

说一句题外话:R的影响力除了在统计分析领域(SAS、SPSS、Statistica已经都开始支持R接口)外,已然发展到了商业数据库领域。

最近两会期间,房地产又一次成为焦点中的焦点,各位代表各抒己见,据说在政协的各项提案之中,关于房地产市场的提案几乎占据半壁江山。

房价涨与不涨,各位代表是各抒己见,有声音说北京房价2年内会涨到4万,而且还有佐证。当然俺们的总理最近5年一直在说这事,童鞋可移步这里,当然还有一张漫画,这里就不贴了,太不Harmany。若感兴趣可以使用 blogtd + 总理姓名 google 之(可能得翻墙出去)。

人家说啥都不如自己看看,来点实际的。关注一下最近几年北京房地产市场每天网上(期房、存量房)签约的套数。

(首先声明,房地产市场比较复杂,比如官啊、商啊、摇号啊、中介啊、银行啊、炒房团啊,空军、多军……指标忒多,所以我一直也没搞太明白。搞不明白也想凑一凑热闹,与时俱进嘛!扔两张图上来,大家笑笑)

2008年9月1日至今的期房(不包含经适房、限价房)签约情况:

其中的时点数据不包括:
  1. 2009.01.25 - 2009.02.01 春节
  2. 2009.11.02,2010.01.10,2010.01.16 调试
  3. 2010.02.13 - 2010.2.19 春节
如果只看2008年后半年,会发现其实每天签约的期房数量也不是很多,一直都在100套左右。不过在年底的时候,随着第一次楼盘降价潮的来临,部分刚需释放,期房签约的数量要明显高于平日。
假设2008年是期房市场正常年的话,那么2009年几乎可以用“疯狂”二字来标记北京的期房市场。每天平均400套的签约数量,动辄200、300万的房价,都贵成这样了,被谁买去啦?
0%