
用R語言做數(shù)據(jù)清理之一:數(shù)據(jù)的清理
數(shù)據(jù)的清理
一份好的,干凈而整潔的數(shù)據(jù)至少包括以下幾個要素:
1、每一個觀測變量構成一列
2、每一個觀測對象構成一行
3、每一個類型的觀測單元構成一個表
就像我們最常接觸的鳶尾花數(shù)據(jù):
## Sepal.Length Sepal.Width Petal.Length Petal.Width Species
## 1 5.1 3.5 1.4 0.2 setosa
## 2 4.9 3.0 1.4 0.2 setosa
## 3 4.7 3.2 1.3 0.2 setosa
## 4 4.6 3.1 1.5 0.2 setosa
## 5 5.0 3.6 1.4 0.2 setosa
每一列就是觀測的指標:花瓣長度,花瓣寬度,萼片長度,萼片寬度,種類;每一行就是一株鳶尾花的觀測值,構成整張表的元素就是四個數(shù)值變量,一個分類分類變量。
然而出于排版的考慮我們抓下來的數(shù)據(jù)往往不是那么的友好,比如說我們可以看到的數(shù)據(jù)通常是這樣的:
## religion <10k 10k-50k 50k-100k
## 1 Agnostic 12 31 23
## 2 Buddhist 58 43 43
## 3 Catholic 79 56 23
而不是:
## religion income freq
## 1 Agnostic <10k 12
## 2 Agnostic 10k-50k 58
## 3 Agnostic 50k-100k 79
## 4 Buddhist <10k 31
當然,除了這種把列表每一列代表一些數(shù)值這種情況外,還有多個變量儲存為一列(比如列表不僅以"<10k","10k-50k","50k-100k"做表頭,甚至還加上性別信息"m<10k","m10k-50k","m50k-100k","f<10k","f10k-50k","f50k-100k",其中m代表男性,f代表女性),還有更過分的將列表的變量不僅儲存在列中,行中也有統(tǒng)計變量。
面對這些不好的table,我們首先要做的就是數(shù)據(jù)管理,將數(shù)據(jù)整理為一個干凈的數(shù)據(jù)集。
數(shù)據(jù)管理
按照en:DAMA的定義:“數(shù)據(jù)資源管理,致力于發(fā)展處理企業(yè)數(shù)據(jù)生命周期的適當?shù)慕?、策略、實踐和程序”。這是一個高層而包含廣泛的定義,而并不一定直接涉及數(shù)據(jù)管理的具體操作(如關系數(shù)據(jù)庫的技術層次上的管理)。我們這里主要講述對于數(shù)據(jù)的變量命名與數(shù)據(jù)的合并,旨在方便數(shù)據(jù)共享。
數(shù)據(jù)管理首先要做的就是大致上了解你的數(shù)據(jù),比如有什么樣的變量,每一行大致長成什么樣,最常用的就是head(),tail().
我們要做的基本上就是這么幾項工作:
給每一個變量命名,而不是V1,V2,如果有必要可以給出code book。
每個變量名最好具有可讀性,除非過長,否則不要用縮寫,例如AgeAtDiagnosis這個命名遠好于AgeDx。
通常來說,最好將數(shù)據(jù)放在一張表里面,如果因為數(shù)據(jù)過多,項目過雜,分成了幾張表。那么一定需要有一列使得這些表之間能夠連接起來,但盡量避免這樣做。
我們以UCI的Human Activity Recognition Using Smartphones Data Set 為例來看看數(shù)據(jù)是如何變成一個基本符合要求的數(shù)據(jù)。這個數(shù)據(jù)我們已經下載下來了,其中關于數(shù)據(jù)的詳細信息可以參閱read me文檔,由于UCI的數(shù)據(jù)通常都是一個基本合乎規(guī)范的數(shù)據(jù)集(主要是指它的數(shù)據(jù)集的變量名都是以V1,V2來命名的)加上一個code book。那么我們看看各個數(shù)據(jù)的名稱(在feature文件里)
setwd("F:/coursera/Data Science/peer assignment/get clean and tidy data/UCI HAR Dataset")name <- read.table("./features.txt", stringsAsFactors = F)
head(name)
## V1 V2
## 1 1 tBodyAcc-mean()-X
## 2 2 tBodyAcc-mean()-Y
## 3 3 tBodyAcc-mean()-Z
## 4 4 tBodyAcc-std()-X
## 5 5 tBodyAcc-std()-Y
## 6 6 tBodyAcc-std()-Z
我們可以看到各個特征的名稱直接標在數(shù)據(jù)上是非常不友善的,我們?yōu)榱俗屗哂锌勺x性,我們以展示在我們眼前的6個數(shù)據(jù)為例:
variablename <- head(name)# 將標簽中的大寫字母轉為小寫,我們這里沒有所以不再賦值,如果需要全變?yōu)榇髮?,可以使用touppertolower(variablename$V2)
## [1] "tbodyacc-mean()-x" "tbodyacc-mean()-y" "tbodyacc-mean()-z"
## [4] "tbodyacc-std()-x" "tbodyacc-std()-y" "tbodyacc-std()-z"
# 將變量名分離成3部分splitNames <- strsplit(variablename$V2, "-")splitNames[[1]]
## [1] "tBodyAcc" "mean()" "X"
# 將變量名合成有意的名稱named <- function(x) { rr <- paste(x[2], x[1], "-", x[3],sep = "")
chartr("()", "of", rr)
}
sapply(splitNames, named)
## [1] "meanoftBodyAcc-X" "meanoftBodyAcc-Y" "meanoftBodyAcc-Z"
## [4] "stdoftBodyAcc-X" "stdoftBodyAcc-Y" "stdoftBodyAcc-Z"
用這樣的名字給數(shù)據(jù)集命名就感覺舒服多了,我們將一些R中對字符串常用的操作函數(shù)總結如下,方便我們對數(shù)據(jù)名稱的修改:
sub:替換字符串中的第一個模式為設定模式(pattern).
gsub:全局替換字符串中的相應模式
grep,grepl:這兩個函數(shù)返回向量水平的匹配結果,grep僅返回匹配項的下標,而grepl返回所有的查詢結果,并用邏輯向量表示有沒有找到匹配。
nchar:統(tǒng)計字符串單字數(shù)目
substr:取子串
paste:將字符串鏈接起來,sep參數(shù)可以設置連接符
str_trim:去掉字符串空格
變量的名稱建議滿足如下要求:
英文變量名盡可能用小寫
盡可能的描述清楚變量特征 (Diagnosis versus Dx)
不要太復雜
不要有下劃線、點、空格
字符型變量應該滿足:
是因子類型的應該轉化為factor
因子盡可能具有一定的描述性 (例如:如果0/1表示真假,那么用TRUE/FALSE代替0/1;在表示性別時用Male/Female代替M/F)
接下來我們討論數(shù)據(jù)集的合并,主要使用函數(shù)merge。
我們以下面兩個數(shù)據(jù)集的合并為例:
df1 <- data.frame(id = sample(1:10), reviewer_id = sample(5:14),time_left = sample(1321:1330),
x = rnorm(10))df2 <- data.frame(id = sample(1:10), answer = rep("B", 10),time_left = sample(321:330),
y = rnorm(10))
head(df1, n = 3)
## id reviewer_id time_left x
## 1 3 9 1326 -0.9232
## 2 10 5 1322 2.5069
## 3 1 14 1330 2.2478
head(df2, n = 3)
## id answer time_left y
## 1 1 B 329 0.8180
## 2 10 B 327 1.4639
## 3 9 B 323 0.8141
merge函數(shù)調用格式為:
merge(x, y, by = intersect(names(x), names(y)),
by.x = by, by.y = by, all = FALSE, all.x = all, all.y = all,
sort = TRUE, suffixes = c(".x",".y"),
incomparables = NULL, ...)
參數(shù)說明:
x,y:兩個數(shù)據(jù)框
by, by.x, by.y:指定用于合并的列的名稱。
all,all.x,all.y:默認的all = FALSE相當于自然連接, 或者說是內部鏈接. all.x = TRUE是一個左連接, all.y = TRUE是一個又連接, all = TRUE 相當于一個外部鏈接.
仔細觀察下面3個例子你就會發(fā)現(xiàn)其中的奧秘:
mergedData <- merge(df1,df2,by.x="reviewer_id",by.y="id",all=TRUE)
head(mergedData)
## reviewer_id id time_left.x x answer time_left.y y
## 1 1 NA NA NA B 329 0.8180
## 2 2 NA NA NA B 330 -0.7706
## 3 3 NA NA NA B 325 -0.4851
mergedData <- merge(df1,df2,by.x="id",by.y="id",all=TRUE)
head(mergedData)
## id reviewer_id time_left.x x answer time_left.y y
## 1 1 14 1330 2.24783 B 329 0.8180
## 2 2 12 1324 1.03181 B 330 -0.7706
## 3 3 9 1326 -0.92317 B 325 -0.4851
## 4 4 7 1321 -0.07841 B 322 0.1801
mergedData2 <- merge(df1,df2,all=TRUE)
head(mergedData2)
## id time_left reviewer_id x answer y
## 1 1 329 NA NA B 0.8180
## 2 1 1330 14 2.2478 <NA> NA
## 3 2 330 NA NA B -0.7706
在plyr包中還提供了join,join_all,arrange等函數(shù)來實現(xiàn)表的連接,但我想merge這個函數(shù)已經足夠用了,所以我們不在多說。當然,在極少數(shù)特別好的情況下(比如列的變量是一致的,或者行的觀測個體是一致的時候)rbind,cbind也是有用的。
有些時候我們會遇到一些特殊的字符串:日期。R中提供了各式各樣的函數(shù)來處理時間:
Sys.setlocale("LC_TIME", "C")
## [1] "C"
x <- c("1jan1960", "2jan1960", "31mar1960", "30jul1960")z <- as.Date(x, "%d%b%Y")
format(z, "%a %b %d")
## [1] "Fri Jan 01" "Sat Jan 02" "Thu Mar 31" "Sat Jul 30"
weekdays(z)
## [1] "Friday" "Saturday" "Thursday" "Saturday"
julian(z)
## [1] -3653 -3652 -3563 -3442
## attr(,"origin")
## [1] "1970-01-01"
transform(z, weekend = as.POSIXlt(z, format = "%Y/%m/%d")$wday %in% c(0, 6))
## X_data weekend
## 1 1960-01-01 FALSE
## 2 1960-01-02 TRUE
## 3 1960-03-31 FALSE
## 4 1960-07-30 TRUE
數(shù)據(jù)分析咨詢請掃描二維碼
若不方便掃碼,搜微信號:CDAshujufenxi
AI 浪潮下的生存與進階: CDA數(shù)據(jù)分析師—開啟新時代職業(yè)生涯的鑰匙(深度研究報告、發(fā)展指導白皮書) 發(fā)布機構:CDA數(shù)據(jù)科 ...
2025-07-13LSTM 模型輸入長度選擇技巧:提升序列建模效能的關鍵? 在循環(huán)神經網絡(RNN)家族中,長短期記憶網絡(LSTM)憑借其解決長序列 ...
2025-07-11CDA 數(shù)據(jù)分析師報考條件詳解與準備指南? ? 在數(shù)據(jù)驅動決策的時代浪潮下,CDA 數(shù)據(jù)分析師認證愈發(fā)受到矚目,成為眾多有志投身數(shù) ...
2025-07-11數(shù)據(jù)透視表中兩列相乘合計的實用指南? 在數(shù)據(jù)分析的日常工作中,數(shù)據(jù)透視表憑借其強大的數(shù)據(jù)匯總和分析功能,成為了 Excel 用戶 ...
2025-07-11尊敬的考生: 您好! 我們誠摯通知您,CDA Level I和 Level II考試大綱將于 2025年7月25日 實施重大更新。 此次更新旨在確保認 ...
2025-07-10BI 大數(shù)據(jù)分析師:連接數(shù)據(jù)與業(yè)務的價值轉化者? ? 在大數(shù)據(jù)與商業(yè)智能(Business Intelligence,簡稱 BI)深度融合的時代,BI ...
2025-07-10SQL 在預測分析中的應用:從數(shù)據(jù)查詢到趨勢預判? ? 在數(shù)據(jù)驅動決策的時代,預測分析作為挖掘數(shù)據(jù)潛在價值的核心手段,正被廣泛 ...
2025-07-10數(shù)據(jù)查詢結束后:分析師的收尾工作與價值深化? ? 在數(shù)據(jù)分析的全流程中,“query end”(查詢結束)并非工作的終點,而是將數(shù) ...
2025-07-10CDA 數(shù)據(jù)分析師考試:從報考到取證的全攻略? 在數(shù)字經濟蓬勃發(fā)展的今天,數(shù)據(jù)分析師已成為各行業(yè)爭搶的核心人才,而 CDA(Certi ...
2025-07-09【CDA干貨】單樣本趨勢性檢驗:捕捉數(shù)據(jù)背后的時間軌跡? 在數(shù)據(jù)分析的版圖中,單樣本趨勢性檢驗如同一位耐心的偵探,專注于從單 ...
2025-07-09year_month數(shù)據(jù)類型:時間維度的精準切片? ? 在數(shù)據(jù)的世界里,時間是最不可或缺的維度之一,而year_month數(shù)據(jù)類型就像一把精準 ...
2025-07-09CDA 備考干貨:Python 在數(shù)據(jù)分析中的核心應用與實戰(zhàn)技巧? ? 在 CDA 數(shù)據(jù)分析師認證考試中,Python 作為數(shù)據(jù)處理與分析的核心 ...
2025-07-08SPSS 中的 Mann-Kendall 檢驗:數(shù)據(jù)趨勢與突變分析的有力工具? ? ? 在數(shù)據(jù)分析的廣袤領域中,準確捕捉數(shù)據(jù)的趨勢變化以及識別 ...
2025-07-08備戰(zhàn) CDA 數(shù)據(jù)分析師考試:需要多久?如何規(guī)劃? CDA(Certified Data Analyst)數(shù)據(jù)分析師認證作為國內權威的數(shù)據(jù)分析能力認證 ...
2025-07-08LSTM 輸出不確定的成因、影響與應對策略? 長短期記憶網絡(LSTM)作為循環(huán)神經網絡(RNN)的一種變體,憑借獨特的門控機制,在 ...
2025-07-07統(tǒng)計學方法在市場調研數(shù)據(jù)中的深度應用? 市場調研是企業(yè)洞察市場動態(tài)、了解消費者需求的重要途徑,而統(tǒng)計學方法則是市場調研數(shù) ...
2025-07-07CDA數(shù)據(jù)分析師證書考試全攻略? 在數(shù)字化浪潮席卷全球的當下,數(shù)據(jù)已成為企業(yè)決策、行業(yè)發(fā)展的核心驅動力,數(shù)據(jù)分析師也因此成為 ...
2025-07-07剖析 CDA 數(shù)據(jù)分析師考試題型:解鎖高效備考與答題策略? CDA(Certified Data Analyst)數(shù)據(jù)分析師考試作為衡量數(shù)據(jù)專業(yè)能力的 ...
2025-07-04SQL Server 字符串截取轉日期:解鎖數(shù)據(jù)處理的關鍵技能? 在數(shù)據(jù)處理與分析工作中,數(shù)據(jù)格式的規(guī)范性是保證后續(xù)分析準確性的基礎 ...
2025-07-04CDA 數(shù)據(jù)分析師視角:從數(shù)據(jù)迷霧中探尋商業(yè)真相? 在數(shù)字化浪潮席卷全球的今天,數(shù)據(jù)已成為企業(yè)決策的核心驅動力,CDA(Certifie ...
2025-07-04