《R語言實戰》第4章 筆記

1.一個示例:

領導行為的性別差異

> #創建leadership數據框> manager <- c(1, 2, 3, 4, 5)> date <- c("10/24/08", "10/28/08", "10/1/08", "10/12/08", "5/1/09")> country <- c("US", "US", "UK", "UK", "UK")> gender <- c("M", "F", "F", "M", "F")> age <- c(32, 45, 25, 39, 99)> q1 <- c(5, 3, 3, 3, 2)> q2 <- c(4, 5, 5, 3, 2)> q3 <- c(5, 2, 5, 4, 1)> q4 <- c(5, 5, 5, NA, 2)> q5 <- c(5, 5, 2, NA, 1)> leadership <- data.frame(manager, date, country, gender, age, q1, q2, q3, q4, q5, stringsAsFactors=FALSE)

2.創建新變數:

算術運算符

> mydata <- data.frame(x1 = c(2, 2, 6, 4),x2 = c(3, 4, 2, 8))> #創建數據框新變數方式一> mydata$sumx <- mydata$x1 + mydata$x2> mydata$meanx <- (mydata$x1 + mydata$x2)/2> #創建數據框新變數方式二> attach(mydata)> mydata$sumx <- x1 + x2> mydata$meanx <- (x1 + x2)/2> detach(mydata)> #創建數據框新變數方式三 (推薦使用)> mydata <- transform(mydata,sumx = x1 + x2,meanx = (x1 + x2)/2)> mydata x1 x2 sumx meanx1 2 3 5 2.52 2 4 6 3.03 6 2 8 4.04 4 8 12 6.0

3.變數的重編碼:

邏輯運算符

語句variable[condition] <- expression將僅在condition的值為TRUE時執行賦值。

> leadership$age[leadership$age == 99] <- NA> #變數的重編碼方式一> leadership$agecat[leadership$age > 75] <- "Elder"> leadership$agecat[leadership$age >= 55 & leadership$age <= 75] <- "Middle Aged"> leadership$agecat[leadership$age < 55] <- "Young"> #變數的重編碼方式二> leadership <- within(leadership,{ agecat <- NA agecat[age > 75] <- "Elder" agecat[age >= 55 & age <= 75] <- "Middle Aged" agecat[age < 55] <- "Young" })> leadership manager date country gender age q1 q2 q3 q4 q5 agecat1 1 10/24/08 US M 32 5 4 5 5 5 Young2 2 10/28/08 US F 45 3 5 2 5 5 Young3 3 10/1/08 UK F 25 3 5 5 5 2 Young4 4 10/12/08 UK M 39 3 3 4 NA NA Young5 5 5/1/09 UK F NA 2 2 1 2 1 <NA>

4.變數的重命名:

> #方式一:互動式> fix(leadership)> #方式一:編程方式> names(leadership)[2] <- "testDate"> names(leadership)[6:10] <- c("item1", "item2", "item3", "item4", "item5")> leadership managerID testDate country gender age item1 item2 item3 item4 item5 agecat1 1 10/24/08 US M 32 5 4 5 5 5 Young2 2 10/28/08 US F 45 3 5 2 5 5 Young3 3 10/1/08 UK F 25 3 5 5 5 2 Young4 4 10/12/08 UK M 39 3 3 4 NA NA Young5 5 5/1/09 UK F NA 2 2 1 2 1 <NA>

5.缺失值:

> #is.na()函數將返回一個相同大小的對象,如果某個元素是缺失值,相應的位置將被改寫為TRUE,不是缺失值的位置則為FALSE> y <- c(1, 2, 3, NA)> is.na(y)[1] FALSE FALSE FALSE TRUE> is.na(leadership[,6:10]) item1 item2 item3 item4 item51 FALSE FALSE FALSE FALSE FALSE2 FALSE FALSE FALSE FALSE FALSE3 FALSE FALSE FALSE FALSE FALSE4 FALSE FALSE FALSE TRUE TRUE5 FALSE FALSE FALSE FALSE FALSE

當你在處理缺失值的時候,你要一直記得兩件重要的事情:

第一,缺失值被認為是不可比較的,即便是與缺失值自身的比較。這意味著無法使用比較運算符來檢測缺失值是否存在。例如,邏輯測試myvar == NA的結果永遠不會為TRUE。作為替代,你只能使用處理缺失值的函數(如 is.na())來識別出R數據對象中的缺失值。

第二,R 並不把無限的或者不可能出現的數值標記成缺失值。正無窮和負無窮分別用Inf和–Inf所標記。因此5/0返回Inf。不可能的值(比如說,sin(Inf))用NaN符號來標記(not a number,不是一個數)。若要識別這些數值,你需要用到is.infinite()或is.nan()。

> #重編碼某些值為缺失值> leadership$age[leadership$age == 99] <- NA

請確保所有的缺失數據已在分析之前被妥善地編碼為缺失值,否則分析結果將失去意義。

> #含有缺失值的算術表達式和函數的計算結果也是缺失值> x <- c(1, 2, NA, 3)> y <- x[1] + x[2] + x[3] + x[4]> y[1] NA> z <- sum(x)> z[1] NA> #好在多數的數值函數都擁有一個na.rm=TRUE選項,可以在計算之前移除缺失值並使用剩餘值進行計算> y <- sum(x, na.rm=TRUE)> y[1] 6> leadership managerID testDate country gender age item1 item2 item3 item4 item5 agecat1 1 10/24/08 US M 32 5 4 5 5 5 Young2 2 10/28/08 US F 45 3 5 2 5 5 Young3 3 10/1/08 UK F 25 3 5 5 5 2 Young4 4 10/12/08 UK M 39 3 3 4 NA NA Young5 5 5/1/09 UK F NA 2 2 1 2 1 <NA>> #函數na.omit()移除所有含有缺失值的觀測> newdata <- na.omit(leadership)> newdata managerID testDate country gender age item1 item2 item3 item4 item5 agecat1 1 10/24/08 US M 32 5 4 5 5 5 Young2 2 10/28/08 US F 45 3 5 2 5 5 Young3 3 10/1/08 UK F 25 3 5 5 5 2 Young

刪除所有含有缺失數據的觀測(稱為行刪除,listwise deletion)是處理不完整數據集的若干手段之一。如果只有少數缺失值或者缺失值僅集中於一小部分觀測中,行刪除不失為解決缺失值問題的一種優秀方法。但如果缺失值遍佈於數據之中,或者一小部分變數中包含大量的缺失數據,行刪除可能會剔除相當比例的數據。我們將在之後探索若干更為複雜精妙的缺失值處理方法。

6.日期值:

as.Date(x, "input_format"),其中x是字元型數據,input_format則給出了用於讀入日期的適當格式。

日期格式

> #日期值的默認輸入格式為yyyy-mm-dd> mydates <- as.Date(c("2007-06-22", "2004-02-13"))> mydates[1] "2007-06-22" "2004-02-13"> strDates <- c("01/05/1965", "08/16/1975")> dates <- as.Date(strDates, "%m/%d/%Y")> dates[1] "1965-01-05" "1975-08-16"> myformat <- "%m/%d/%y"> leadership$testDate[1] "10/24/08" "10/28/08" "10/1/08" "10/12/08" "5/1/09"> leadership$testDate <- as.Date(leadership$testDate, myformat)> leadership$testDate[1] "2008-10-24" "2008-10-28" "2008-10-01" "2008-10-12" "2009-05-01"> #此時的日期和時間> Sys.Date()[1] "2017-02-21"> date()[1] "Tue Feb 21 20:33:46 2017"> today <- Sys.Date()> format(today,format="%B %d %Y")[1] "二月 21 2017"> format(today,format="%A")[1] "星期二"> startdate <- as.Date("2004-02-13")> enddate <- as.Date("2011-01-22")> days <- enddate - startdate> daysTime difference of 2535 days> #函數difftime()來計算時間間隔,並以星期、天、時、分、秒來表示> today <- Sys.Date()> dob <- as.Date("1956-10-12")> difftime(today, dob, units="weeks")Time difference of 3149.571 weeks > #函數as.character()可將日期值轉換為字元型> strDates <- as.character(dates)> strDates[1] "1965-01-05" "1975-08-16"

7.類型轉換:

R與其他統計編程語言有著類似的數據類型轉換方式。舉例來說,向一個數值型向量中添加一個字元串會將此向量中的所有元素轉換為字元型。

類型轉換函數

名為is.datatype()這樣的函數返回TRUE或FALSE,而as.datatype()這樣的函數則將其參數轉換為對應的類型。

> a <- c(1,2,3)> a[1] 1 2 3> is.numeric(a)[1] TRUE> is.vector(a)[1] TRUE> a <- as.character(a)> a[1] "1" "2" "3"> is.numeric(a)[1] FALSE> is.vector(a)[1] TRUE> is.character(a)[1] TRUE

8.數據排序:

可以使用order()函數對一個數據框進行排序。默認的排序順序是升序,在排序變數的前邊加一個減號即可得到降序的排序結果。

> #創建了一個新的數據集,其中各行依經理人的年齡升序排序> newdata <- leadership[order(leadership$age),]> newdata managerID testDate country gender age item1 item2 item3 item4 item5 agecat3 3 2008-10-01 UK F 25 3 5 5 5 2 Young1 1 2008-10-24 US M 32 5 4 5 5 5 Young4 4 2008-10-12 UK M 39 3 3 4 NA NA Young2 2 2008-10-28 US F 45 3 5 2 5 5 Young5 5 2009-05-01 UK F NA 2 2 1 2 1 <NA>> #將各行依女性到男性、同樣性別中按年齡升序排序> attach(leadership)> newdata <- leadership[order(gender,age),]> detach(leadership)> newdata managerID testDate country gender age item1 item2 item3 item4 item5 agecat3 3 2008-10-01 UK F 25 3 5 5 5 2 Young2 2 2008-10-28 US F 45 3 5 2 5 5 Young5 5 2009-05-01 UK F NA 2 2 1 2 1 <NA>1 1 2008-10-24 US M 32 5 4 5 5 5 Young4 4 2008-10-12 UK M 39 3 3 4 NA NA Young> #將各行依經理人的性別和年齡降序排序> attach(leadership)> newdata <- leadership[order(gender,-age),]> detach(leadership)> newdata managerID testDate country gender age item1 item2 item3 item4 item5 agecat5 5 2009-05-01 UK F NA 2 2 1 2 1 <NA>2 2 2008-10-28 US F 45 3 5 2 5 5 Young3 3 2008-10-01 UK F 25 3 5 5 5 2 Young4 4 2008-10-12 UK M 39 3 3 4 NA NA Young1 1 2008-10-24 US M 32 5 4 5 5 5 Young

9.數據集的合併:

> #將dataframeA和dataframeB按照ID進行了合併> total <- merge(dataframeA, dataframeB, by="ID")> #將兩個數據框按照ID和Country進行了合併> total <- merge(dataframeA, dataframeB, by=c("ID","Country"))> #如果要直接橫向合併兩個矩陣或數據框,並且不需要指定一個公共索引,那麼可以直接使用cbind()函數,這個函數將橫向合併對象A和對象B。為了讓它正常工作,每個對象必須擁有相同的行數,以同順序排序> total <- cbind(A, B)> #要縱向合併兩個數據框(數據集),請使用rbind()函數> total <- rbind(dataframeA, dataframeB)

10.數據集取子集:

> #選入(保留)變數> newdata <- leadership[, c(6:10)]> newdata item1 item2 item3 item4 item51 5 4 5 5 52 3 5 2 5 53 3 5 5 5 24 3 3 4 NA NA5 2 2 1 2 1

> #剔除(丟棄)變數方式一> myvars <- names(leadership) %in% c("item3", "item4")> myvars [1] FALSE FALSE FALSE FALSE FALSE FALSE FALSE TRUE TRUE FALSE FALSE> newdata <- leadership[!myvars]> newdata managerID testDate country gender age item1 item2 item5 agecat1 1 2008-10-24 US M 32 5 4 5 Young2 2 2008-10-28 US F 45 3 5 5 Young3 3 2008-10-01 UK F 25 3 5 2 Young4 4 2008-10-12 UK M 39 3 3 NA Young5 5 2009-05-01 UK F NA 2 2 1 <NA>

剔除變數q3和q4。為了理解以上語句的原理,你需要把它拆解如下:

(1) names(leadership) 生成了一個包含所有變數名的字元型向量:c("managerID","testDate","country","gender","age","item1", "item2","item3","item4","item5")。

(2) names(leadership) %in% c("item3", "item4") 返回了一個邏輯型向量,names(leadership)中每個匹配item3或item4的元素的值為TRUE,反之為FALSE:c(FALSE, FALSE,FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, FALSE)。

(3) 運算符非(!)將邏輯值反轉:c(TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE,FALSE, TRUE)。

(4) leadership[c(TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE,TRUE)]選擇了邏輯值為TRUE的列,於是item3和item4被剔除了。

> #剔除(丟棄)變數方式二> newdata <- leadership[c(-8,-9)]> newdata managerID testDate country gender age item1 item2 item5 agecat1 1 2008-10-24 US M 32 5 4 5 Young2 2 2008-10-28 US F 45 3 5 5 Young3 3 2008-10-01 UK F 25 3 5 2 Young4 4 2008-10-12 UK M 39 3 3 NA Young5 5 2009-05-01 UK F NA 2 2 1 <NA>

這種方式的工作原理是,在某一列的下標之前加一個減號(–)就會剔除那一列。

> #剔除(丟棄)變數方式三> leadership$item3 <- leadership$item4 <- NULL> leadership managerID testDate country gender age item1 item2 item5 agecat1 1 2008-10-24 US M 32 5 4 5 Young2 2 2008-10-28 US F 45 3 5 5 Young3 3 2008-10-01 UK F 25 3 5 2 Young4 4 2008-10-12 UK M 39 3 3 NA Young5 5 2009-05-01 UK F NA 2 2 1 <NA>

這回你將item3和item4兩列設為了未定義(NULL)。注意,NULL與NA(表示缺失)是不同的。

丟棄變數是保留變數的逆向操作。選擇哪一種方式進行變數篩選依賴於兩種方式的編碼難易程度。如果有許多變數需要丟棄,那麼直接保留需要留下的變數可能更簡單,反之亦然。

> newdata <- leadership[1:3,]> newdata managerID testDate country gender age item1 item2 item5 agecat1 1 2008-10-24 US M 32 5 4 5 Young2 2 2008-10-28 US F 45 3 5 5 Young3 3 2008-10-01 UK F 25 3 5 2 Young > newdata <- leadership[leadership$gender=="M" & leadership$age > 30,]> newdata managerID testDate country gender age item1 item2 item5 agecat1 1 2008-10-24 US M 32 5 4 5 Young4 4 2008-10-12 UK M 39 3 3 NA Young> leadership managerID testDate country gender age item1 item2 item5 agecat1 1 2008-10-24 US M 32 5 4 5 Young2 2 2008-10-28 US F 45 3 5 5 Young3 3 2008-10-01 UK F 25 3 5 2 Young4 4 2008-10-12 UK M 39 3 3 NA Young5 5 2009-05-01 UK F NA 2 2 1 <NA>> newdata <- subset(leadership, age >= 35 | age < 24,select=c(item1, item2))> newdata item1 item22 3 54 3 3> newdata <- subset(leadership, gender=="M" & age > 25,select=gender:item5)> newdata gender age item1 item2 item51 M 32 5 4 54 M 39 3 3 NA

總結:本章講解了大量的基礎知識。首先我們看到了R存儲缺失值和日期值的方式,並探索了它們的多種處理方法。接著學習了如何確定一個對象的數據類型,以及如何將它轉換為其他類型。還使用簡單的公式創建了新變數並重編碼了現有變數。你學習了如何對數據進行排序和對變數進行重命名,學習了如何對數據和其他數據集進行橫向合併(添加變數)和縱向合併(添加觀測)。最後,我們討論了如何保留或丟棄變數,以及如何基於一系列的準則選取觀測。通過這些基本的數據管理知識能讓我們更好地管理我們的數據,讓數據分析發揮更大的作用,通過不同方法達到同樣的目的反覆地實踐代碼,是掌握本章內容的關鍵。


推薦閱讀:

七周成為數據分析師—Excel實戰篇
什麼是數據化管理
技巧——新建日期表
2017上半年總結:數據分析轉行成功
柱形圖,百分比堆積柱形圖,簇狀柱形圖等圖表統統「一網打盡」!

TAG:数据分析 | R编程语言 |