1. 程式人生 > >R語言修改文字

R語言修改文字

需求:使用R語言對儲存在文字檔案中的一個引數進行修改,檔案結構如下,檔案資料量較大,但每次只需修改第20行的引數。

常規解決方案:讀到記憶體,修改,寫出

問題:讀寫檔案耗費時間

解決方案1:

使用seek(con,where,rw){base}函式定位到所需的位置(where及相關引數確定偏移),直接將該行重寫writeLines(text,con)

紅框中內容分別表示所需修改文字的位置及其對應的偏移位置

con<-file("84.063346096_32.321391739.txt","r+")
seek(con,1061,rw = "write")
writeLines("275.821",con)
close(con)

問題:每行的字元長度不確定,第11行到第12行數字有效位數不同,因此每個檔案裡使用1061不具有可操作性

解決方案2:

可通過readLines(con,n)中的n控制指標位置到第20行,再結合seek(...,origin)的origin = 'current'獲取偏移位置

seek函式返回的是當前所在的游標位置,第一次呼叫seek(),返回結果為0表示讀取文字游標和寫入文字游標並不相同,儘管前面已經讀取了前五行,但並未寫入,故仍為0.但第二次呼叫seek函式,返回的結果卻是4174讓人費解...

> con <- file("84.063346096_32.321391739.txt","r+")
> readLines(con,5)
[1] "&METADATA_NAMELIST"                                                   
[2] " startdate             = \"197301010000\""                            
[3] " enddate               = \"201301010000\"con testfor_a_while      = 0"
[4] " output_dir            = \"D:/Noah/\""                                
[5] " Latitude              = 32.321391739"                                
> seek(con,25,rw = "write",origin = "current")
[1] 0
> seek(con,25,rw = "write",origin = "current")
[1] 4174
> seek(con,25,rw = "write",origin = "current")
[1] 4199

注意4175

> con <- file("84.063346096_32.321391739.txt","r+")
> readLines(con,2)
[1] "&METADATA_NAMELIST" " startest2"        
> seek(con,25,rw = "write",origin = "current")
[1] 0
> seek(con,25,rw = "write",origin = "current")
[1] 4175
> seek(con,25,rw = "write",origin = "current")
[1] 4200
> close(con)

如下的結果是能夠理解的,每次偏移當前位置25個,第一次呼叫時,其初始狀態為0,每次偏移增加25,產生累加效應

> con <- file("84.063346096_32.321391739.txt","r+")
> seek(con,25,rw = "write",origin = "current")
[1] 0
> seek(con,25,rw = "write",origin = "current")
[1] 25
> seek(con,25,rw = "write",origin = "current")
[1] 50
> seek(con,25,rw = "write",origin = "current")
[1] 75

解釋:R中,雖然seek函式支援讀/寫指標,但是對windows支援並不好,如下所示,上述測試的問題可能由此導致。

Warning

Use of seek on Windows is discouraged. We have found so many errors in the Windows implementation of file positioning that users are advised to use it only at their own risk, and asked not to waste the R developers' time with bug reports on Windows' deficiencies.

最終解決方案:

讀取前19行文字readLines(),計算其字元數目nchar(),即獲取對應第20行的位置,後續相同

其中,readLines()返回的結果並不包含換行符“\n”,而這是佔2個位置的,因此,需要加上19*2

總結:

使用R語言進行文字資料的處理效率不高,R語言更擅長與結構化資料的處理。如同在資料探勘中反覆強調的一個觀點:資料的清洗和修剪是最耗費時間的一部分工作(我也不知道是誰說的,個人經驗)。在解決這個問題時,應當充分考慮可IO開銷。放在整個專案中,需要對2w+個氣象驅動資料進行類似的操作,若反覆讀寫所帶來的代價過大。