99999久久久久久亚洲,欧美人与禽猛交狂配,高清日韩av在线影院,一个人在线高清免费观看,啦啦啦在线视频免费观看www

熱線電話:13121318867

登錄
首頁精彩閱讀用R語言做數(shù)據(jù)清理之一:數(shù)據(jù)的清理
用R語言做數(shù)據(jù)清理之一:數(shù)據(jù)的清理
2017-04-07
收藏

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

數(shù)據(jù)分析師考試動態(tài)
數(shù)據(jù)分析師資訊
更多

OK
客服在線
立即咨詢
客服在線
立即咨詢
') } function initGt() { var handler = function (captchaObj) { captchaObj.appendTo('#captcha'); captchaObj.onReady(function () { $("#wait").hide(); }).onSuccess(function(){ $('.getcheckcode').removeClass('dis'); $('.getcheckcode').trigger('click'); }); window.captchaObj = captchaObj; }; $('#captcha').show(); $.ajax({ url: "/login/gtstart?t=" + (new Date()).getTime(), // 加隨機數(shù)防止緩存 type: "get", dataType: "json", success: function (data) { $('#text').hide(); $('#wait').show(); // 調用 initGeetest 進行初始化 // 參數(shù)1:配置參數(shù) // 參數(shù)2:回調,回調的第一個參數(shù)驗證碼對象,之后可以使用它調用相應的接口 initGeetest({ // 以下 4 個配置參數(shù)為必須,不能缺少 gt: data.gt, challenge: data.challenge, offline: !data.success, // 表示用戶后臺檢測極驗服務器是否宕機 new_captcha: data.new_captcha, // 用于宕機時表示是新驗證碼的宕機 product: "float", // 產品形式,包括:float,popup width: "280px", https: true // 更多配置參數(shù)說明請參見:http://docs.geetest.com/install/client/web-front/ }, handler); } }); } function codeCutdown() { if(_wait == 0){ //倒計時完成 $(".getcheckcode").removeClass('dis').html("重新獲取"); }else{ $(".getcheckcode").addClass('dis').html("重新獲取("+_wait+"s)"); _wait--; setTimeout(function () { codeCutdown(); },1000); } } function inputValidate(ele,telInput) { var oInput = ele; var inputVal = oInput.val(); var oType = ele.attr('data-type'); var oEtag = $('#etag').val(); var oErr = oInput.closest('.form_box').next('.err_txt'); var empTxt = '請輸入'+oInput.attr('placeholder')+'!'; var errTxt = '請輸入正確的'+oInput.attr('placeholder')+'!'; var pattern; if(inputVal==""){ if(!telInput){ errFun(oErr,empTxt); } return false; }else { switch (oType){ case 'login_mobile': pattern = /^1[3456789]\d{9}$/; if(inputVal.length==11) { $.ajax({ url: '/login/checkmobile', type: "post", dataType: "json", data: { mobile: inputVal, etag: oEtag, page_ur: window.location.href, page_referer: document.referrer }, success: function (data) { } }); } break; case 'login_yzm': pattern = /^\d{6}$/; break; } if(oType=='login_mobile'){ } if(!!validateFun(pattern,inputVal)){ errFun(oErr,'') if(telInput){ $('.getcheckcode').removeClass('dis'); } }else { if(!telInput) { errFun(oErr, errTxt); }else { $('.getcheckcode').addClass('dis'); } return false; } } return true; } function errFun(obj,msg) { obj.html(msg); if(msg==''){ $('.login_submit').removeClass('dis'); }else { $('.login_submit').addClass('dis'); } } function validateFun(pat,val) { return pat.test(val); }