写
在前面
本期“大猫R语言公众号”仍由“村长”供稿。村长继续为大家奉上data.table使用案例心得,希望大家能够继续支持村长!!
问
题:批量处理表中变量
正式开始说问题之前,我们先回顾一下data.table的基本语句DT[i, j, by],简而言之,"i"是对行进行选择,"j"是对列进行操作,"by"是分组。我们现在要对列进行操作(转换类型),因此本期是关于“j”的内容。
下面正式开始,笔者在帮他人处理数据时遇到了需要同时为一系列变量进行相同处理,先来看数据结构:
我们要做的是从第3个变量“除权除息日[报告期]2010年一季”开始,一直到第34个变量,将这些变量全部转化为Date格式。
直
观处理法:分别处理每一个变量
大家最直观的处理方法,肯定是把每一个变量写在j中然后分别进行日期格式的修改,诸如如下形式:
DT[, ':='(`除权除息日rn[报告期] 2010一季` = as.Date(`除权除息日rn[报告期] 2010一季`, ....))]
不知道大家对这种写法怎么看,笔者是完全无法忍受这样的代码的。首先,变量的数量实在太多,如果输这34个变量名尚且能接受的话,那万一要是有100个变量呢,“输”了你赢了世界又如何;再者,未经过清洗和结构化的变量名存在着太多难以预计的问题,我们来看代码中这个示例的变量名:`除权除息日rn[报告期] 2010一季`,这是一个非常脏的原始数据变量名,除了变量名是中文,需要用``符号进行引用以外,中间还有不知道什么时候会冒出来的空格、换行符等等,笔者也是试了好几次才真正将变量名输入正确。只能说我“输”了,但你肯定是怕了...
批
量处理法:用lapply批量处理变量
在此时lapply的妙用就显现出来了,在R中lapply用来对list中每一个element进行相同处理,如何把它运用到data.table,话不多说先上代码:
DT[, colnames(DT[, 3:34]) := lapply(.SD[, 3:34], as.Date)]
结果如下:
下面就让笔者来为大家解释这一段代码:
首先,我们看 ':=' 的右边。我们知道在data.table包中,.SD是经过i和by处理之后剩下的那部分数据集,它的格式是一个data.table,同时它是一个list。而我们要处理的变量是第3个到第34个,所以在.SD中选出3至34列,运用lapply对选中的.SD[, 3:34]里面每一个element使用as.Date函数。
再看,':='的左边。如何把处理好的这些变量与变量名进行对应,这里就用到了colnames()这个函数,提取出我们这个data.table第3到第34个变量的名字,这样就可以将变量名和更改格式后的变量按顺序进行一一匹配。
注
意事项:.SD用法
可以说.SD是data.table处理中非常重要的一个用法,但也切勿乱用,在这里笔者发现了一个关于.SD的问题,首先我们改一下代码:
# 将 := 左边的DT改成.SD ----
DT[, colnames(.SD[, 3:34]) := lapply(.SD[, 3:34], as.Date)]
我们将 := 左边的DT改成了.SD,下面来看看运行结果:
运行有报错,这就需要注意.SD的用法了,我们首先看报错提示语句的意思是::=的左边并不是字符、整数或者数值格式。为了更加深入认识这个问题,我们下边再写一段代码,用.SD方法输出的colnames:
DT[, colnames(.SD)]
输出结果如下:
输出结果非常正常,那么只能证明一点:.SD不能用在 := 的左边!!!大家在运用的过程中必须要注意。
下
期预告
下期的大猫R语言课堂还是由村长来进行撰写和推送,届时将会给大家带来一个比较有趣的data.table发现,敬请期待!!
大猫的R语言课堂
我是大猫,一个高中读文科但却在代码、数学的路上狂奔不止的Finance Ph. D Candidate。
我是村长,一个玩了9年指弹吉他,却被代码深深吸引的博士候选人。
大猫的微信号是:
iRoss2007
村长的B站主页是:http://space.bilibili.com/40771572