寫
在前面
本期“大貓R語言公衆号”仍由“村長”供稿。村長繼續為大家奉上data.table使用案例心得,希望大家能夠繼續支援村長!!
問
題:批量處理表中變量
正式開始說問題之前,我們先回顧一下data.table的基本語句DT[i, j, by],簡而言之,"i"是對行進行選擇,"j"是對列進行操作,"by"是分組。我們現在要對列進行操作(轉換類型),是以本期是關于“j”的内容。
下面正式開始,筆者在幫他人處理資料時遇到了需要同時為一系列變量進行相同處理,先來看資料結構:
我們要做的是從第3個變量“除權除息日[報告期]2010年一季”開始,一直到第34個變量,将這些變量全部轉化為Date格式。
直
觀處理法:分别處理每一個變量
大家最直覺的處理方法,肯定是把每一個變量寫在j中然後分别進行日期格式的修改,諸如如下形式:
DT[, ':='(`除權除息日\r\n[報告期] 2010一季` = as.Date(`除權除息日\r\n[報告期] 2010一季`, ....))]
不知道大家對這種寫法怎麼看,筆者是完全無法忍受這樣的代碼的。首先,變量的數量實在太多,如果輸這34個變量名尚且能接受的話,那萬一要是有100個變量呢,“輸”了你赢了世界又如何;再者,未經過清洗和結構化的變量名存在着太多難以預計的問題,我們來看代碼中這個示例的變量名:`除權除息日\r\n[報告期] 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