R資料處理-讀取指定欄寬格式的文字資料檔(.dat)[Stack Overflow練題001]

nearlin314159
·
(edited)
·
IPFS
若需要分析的資料是固定欄寬格式(Fixed Width Format, fwf)的純文字檔,需要透過ddf或sps工作檔正確指定欄位分隔、變項名稱,請看今天的練習。

資料處理的第一步是讀取資料檔,而資料檔格式五花八門,較常見幾種的有.sav、.dta、.xlsx、.csv、.dat等。

其中SPSS與Stata等套裝軟體提供的資料檔格式(即.sav、.dta)逐漸變得更加熱門,因為可以直接設定variable labels、value labels、欄位類型等,使用者匯入資料檔即可取得所有資訊,不需要另外使用資料設定工作檔或codebook。雖然檔案容量較大與處理費時是其缺點,但當代電腦硬碟容量動輒數百GB甚至數TB,效能也愈發強悍,對一般使用者而言缺點就變得微不足道了。

然而,現在仍可以看到一些資料是以.dat等純文字檔格式提供,主要是以下兩種:

  1. 行之有年的調查資料庫:早期以純文字檔釋出資料,後期雖然科技進步,但為保持一致性或工作流程已經固定,就會繼續以文字檔釋出。

  2. 極為大量的資料:數千甚至上萬筆的資料,容量都不會造成現代電腦的負擔,但部分特殊資料庫的資料量以百萬筆計,單一資料檔即可能達數十GB,使用套裝軟體的檔案格式會需要很多時間讀取。


今天在Stack Overflow看到的提問是使用者想匯入美國勞工統計局執行的Current Population Survey資料,提問原帖在此

若用記事本開啟.dat檔,內容大致是這樣:

用notepad++開啟CPS的.dat資料檔

視覺上來說,會自然以為這是以空格(space)分隔的資料檔,所以提問者一開始是使用read.delim這個函數匯入資料,read.delim是用來讀取分隔符號格式(Delimited Format)的資料檔,只要正確指定分隔符號,就能將用分隔符號隔開的資料讀取成不同欄位,例如.csv(逗號分隔)。

以這個資料檔來說這樣的處理並不正確。查看CPS的相關說明即可得知資料是固定欄寬格式,取前幾個變項為例:

hrhhid     1-15 (a)
hrmonth    16-17
hryear4    18-21
hurespli   22-23
hufinal    24-26

這表示第1~15個字元是第一個變項(hrhhid),第16~17字元是第二個變項(hrmonth),注意這邊的字元包含空格。因此正確的前5個變項是以下圖中的灰線劃分。

正確劃分前5個欄位的.dat檔

明白問題出在哪後,接下來只要正確指派每個欄位佔據的字元就可以了。然而,查看技術說明文件並手動輸入是相當費時的工作。幸好CPS有提供套裝軟體的資料設定工作檔。雖然是提供給SAS、SPSS、STATA使用者讀取資料時直接使用的,但R中有套件可以直接讀取這些工作檔,並在R中進行相同的處理。

library(asciiSetupReader)

cps2004may <- read_ascii_setup(
  data = dat_path,
  setup_file = sps_path
)

其中dat_path是.dat檔存放路徑,setup_file則是.sps檔(資料設定工作檔)存放路徑。如此便能正確讀取有提供資料設定工作檔的fwf .dat了。


如果沒有提供資料設定工作檔怎麼辦?那就只能參考技術說明文件逐一指派每個欄位的寬度了。不過在原帖中也有人分享如何透過程式處理技術說明文件,一次性整理好每個欄位的寬度,若大家有興趣將來再做個分析講解吧!


CC BY-NC-ND 4.0

Like my work? Don't forget to support and clap, let me know that you are with me on the road of creation. Keep this enthusiasm together!