京寵展信息指南
1586
2022-05-30
1.1.3 read.table—任意分隔符數據讀取
read.table函數會將文件讀成數據框的格式,將分隔符作為區分變量的依據,把不同的變量放置在不同的列中,每一行的數據都會對應相應的變量名稱進行排放。表1-1簡要列出了read.table函數中主要參數的中英文對照。
表1-1 函數read.table實用參數及功能對照
以上這些參數已足以應付讀取日常練習所用的規整的數據文件,例如,教授布置的統計作業中的原始數據集,各種傳感器輸出的.csv文件等。下面的代碼及運行結果演示非常簡單,使用read.table讀取1.1.1節中的第一個數據集,實現思路是每次只增加一個read.table函數中的參數。代碼如下:
> flights <- read.table(file = "flights.csv")
> head(x = flights)
表1-2展示了所有參數均為默認設置的部分結果。
表1-2 read.table函數參數設置結果展示一
小提示
上面的演示代碼中使用了head函數,該函數可以按照人們習慣的方式將數據框按照自上而下的方式顯示出來,而不是像str函數那樣從左向右展示。一般在做初步數據檢視的時候,推薦兩個函數都運行,作為互補。head方便與原始數據文檔進行比對,而str則可以顯示所保存的數據框屬性、變量類型等信息。
因為函數默認的分隔符是空白(注意不是空格),所以應有的6個變量都被讀在一列中。且默認的header參數是假,所以數據變量被默認分配了一個新的變量名V1,并且應為變量名稱的這一行變成了觀測值的第一行。將header設置為TRUE后的代碼如下:
> flights <- read.table(file = "flights.csv",header = TRUE)
> head(x = flights)
表1-3中顯示的是部分結果。
表1-3 read.table函數參數設置結果展示二
指定header參數為真,分隔符sep參數為“,”后,變量名稱才得以讀取成應有的樣子(如表1-4所示)。
> flights <- read.table(file = "flights.csv",header = TRUE,sep = ",")
> head(flights)
表1-4 read.table函數參數設置結果展示三
表1-4所示的數據框終于呈現了該有的樣子。需要注意的,是因為字符數據因子化的參數還是默認設置,因此變量carrier、tailnum、origin、dest還是因子型。在實際練習或使用時,建議指定stringAsFactors = FALSE。
以上讀取的數據集都是規整的數據集,即每一行數據都有相同的觀測值。不過在實際生活中,原始數據難免會存在空白行、空白值、默認值,或者某一行數據存在多余觀測值卻沒有與之對應的變量名稱,抑或元數據和原始數據在同一個文件中等各種問題。這里暫且稱這些問題數據集為不規則數據集,簡單說就是,實際列的個數多于列名的個數。read.table函數為這些問題準備了相應的參數。
1.空白行
表1-1中介紹過read.table對于空白行的默認處理是跳過,這可以滿足大部分常見數據的情況。不過在某些特殊情況下,例如,一個數據文件中同時存在兩個或兩個以上的數據集,那么保留空白行可能會有助于后續的數據處理。表1-5演示的就是一個比較特殊的例子。空白行的上部是元數據,也即解釋數據的數據,這里演示的是航空公司的縮寫和全名的對照。空白行的下部是數據的主體部分,航班號、起始地縮寫、起飛時間。這里保留空白行可有助于區分數據的不同部分。
表1-5 特殊類型文本數據文檔
保留空白行的代碼如下所示:
> airlines <- read.table(file = "airlines.csv", header = TRUE, sep = "\t", blank.lines.skip = FALSE, stringsAsFactors = FALSE)
> head(airlines, n = 8)
指定空白行保留的參數后,數據被成功讀進R(表1-6)。
表1-6 read.table函數參數設置結果展示四
如此一來,不同的數據集就可以很容易地進行切割并歸集到新的數據集中。可是,另外一個問題又出現了,函數按照第一部分的兩列變量將后續的所有數據也都寫入了兩列。這是因為read.table會掃描文件中前五行的數據(包括變量名稱)并以此為標準來確定變量數,airlines.csv中開始的五行數據都只有兩列,所以后續的數據也都強制讀取成兩列。如果數據的第2~5行中存在任何一行擁有多于前面一行或幾行的數據值,那么函數就會報錯提示第一行沒有相應數量的值。這種情況可以根據實際數據文件內容,用兩種方式來處理,具體如下。
1)如果文件中開始的部分是暫時不需要的元數據,那么可以使用skip函數跳過相應的行數,只讀取感興趣的數據。
2)如果文件內容是一個整體,只是若干行數據具有額外的觀測值。那么可以通過調整參數col.names或fill和header進行處理。
第一種情況比較容易,讀者可以自行測試,在此略過。第二種情況需要知道數據中觀測值個數的最大值,以用來補齊變量個數。因為已經知道airlines文件的第二部分擁有6個變量,所以下面就來演示如何將6個變量名稱指定成新的變量名(表1-7),代碼如下:
> airlines <- read.table(file = "airlines.csv", header = FALSE, sep = "\t", stringsAsFactors = FALSE, col.names = paste0("V",1:6), blank.lines.skip = FALSE)
> head(airlines)
演示結果如表1-7所示。
表1-7 read.table函數參數設置結果展示五
小技巧:
另外一個獲取不規則數據集中所需變量個數的方法是利用報錯信息。當不指定col.names參數,且原始數據的第2~5行中任一行有多于第一行的數據時,read.table會報錯提示Error in scan(file = file, what = what, sep = sep, quote = quote, dec = dec, : line 1 did not have X elements, X即所需要的手動指定的變量個數。
這里使用paste0來創建新的變量名稱。paste0可以理解為膠水函數,用于將需要的字符串粘合在一起。這里演示的意思是創建6個以V開頭,從V1到V6的字符串作為變量名。這種處理方式足以應付平時練習用的小型數據集(比如,只有幾行到幾十行數據的數據集)。但是在處理實際工作中成百上千行的數據時,這種手動指定變量個數的方法就顯得笨拙而低效了。下面的代碼演示了如何實現自動檢測數據集所需的變量數:
> number_of_col <- max(count.fields("airlines.csv",sep = "\t"))
> airlines <- read.table(file = "airlines.csv", header = FALSE, sep = "\t", stringsAsFactors = FALSE, col.names = paste0("V",seq_len(number_of_col)), blank.lines.skip = FALSE)
> head(airlines)
部分結果展示如表1-8所示。
表1-8 read.table函數參數設置結果展示六
count.fields/max/seq_len這三個函數的配合使用實現了如下功能。
count.fields用于自動檢測數據集中每一行數據的觀測值個數,max用于找出count.fields輸入結果中的最大值,seq_len用于以最大值為參照生成1到最大值的整數序列,膠水函數paste0用于定義變量名稱。
因為R基于向量計算的特性,因此這種函數之間簡單的配合使用很常見也很有效。所以希望小伙伴們在以后的練習或實際工作中,多思考,盡量使用這樣的組合來提高代碼的效率、簡潔性和可重復性。
使用參數fill和header也可以讀取不規則數據集。需要注意的是,采用這種方法是有前提條件的,即原始數據第2~5行實際列的個數應大于列名。代碼如下:
> flights_uneven <- read.table("airlines.csv", header = FALSE, sep = "\t", stringsAsFactors = FALSE, fill = TRUE)
> head(flights_uneven)
上述代碼的演示結果如表1-9所示。
表1-9 read.table函數參數設置結果展示七
2.默認值、空白
一個數據集里出現默認值(NA)或空白(“”)的情況十分常見,兩者之間的區別需要根據不同的實際情況來確定。理論上來講,默認值仍是數據觀測值的一種,雖然在原始數據中其可能與空白一樣沒有顯示,但是它可以通過其他手段來進行補齊。而空白有可能并不是數據,比如在上面的演示中,V3至V6列,1~5行都是空白,這些空白不屬于任何實際數據變量,是真正的空白,因而不能說這些空白是默認值。默認值和空白的處理完全可以獨立成書,因為相關內容已經超出了本書的范圍,所以這里不再過多討論。下面只演示在導入數據的過程中,如何進行簡單的默認值、空白預處理,代碼如下:
> flights_uneven <- read.table(file = "flights_uneven.csv", header = FALSE, sep = "\t", stringsAsFactors = FALSE, fill = TRUE, na.strings = c(""))
> head(flights_uneven)
表1-10中展示了處理后的部分數據值。
表1-10 read.table函數參數設置結果展示八
第七列中的數據在指定將空白替換成“NA”之后,原有的空白位置被寫入了“NA”,也就是說第七列的空白屬于數據的一部分。根據實際情況,也可以將多余的數據部分或全部替換成“NA”(如表1-11所示),以方便后續的處理及分析,代碼如下:
> flights_uneven <- read.table("flights_uneven.csv",sep = "\t", stringsAsFactors = FALSE, fill = TRUE,header = FALSE, na.strings = c(paste0("測試",1:3),""))
> head(flights_uneven)
替換結果如表1-11所示。
表1-11 read.table函數參數設置結果展示九
當數據集行數較多,無法輕易地鑒別出某一列到底有多少個觀測值需要賦值為“NA”的時候,可以配合unique函數進行處理。處理的思路是先將數據讀取到R中,然后使用unique函數找到指定列中的非重復觀測值,選取指定觀測值并保存到一個向量內,然后將向量指定給na.strings參數來進行替換,代碼如下:
> flights_uneven <- read.table("flights_uneven.csv",sep = "\t", string-sAsFactors = FALSE, fill = TRUE, header = FALSE)
> replace <- unique(flights_uneven$V7)
replace
[1] ""????? "測試1" "測試2" "測試3"
> flights_uneven <- read.table("flights_uneven.csv",sep = "\t", stringsAsFactors = FALSE, fill = TRUE,header = FALSE, na.strings = c(replace[c(1,3)]))
> head(flights_uneven)
替換結果如表1-12所示。
表1-12 read.table函數參數設置結果展示十
第一次讀取數據是為了獲得需要替換的觀測值,第二次讀取則是將需要替換成“NA”的觀測值指定給相應參數。因為replace是一個字符串向量,所以可以使用“[”按位置選擇其中的值,當然也可以不選擇任何值,直接全部替換。
小知識
“[”是baseR中Extract的一種,在R的使用過程中,這是必須掌握和理解的函數之一。
其他
版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。