感謝Robert I.Kabacoff 著作本書爽蝴,同時(shí)感謝高濤、肖楠、陳鋼編譯此書梅惯。
最近在學(xué)習(xí)《R語言實(shí)戰(zhàn)》,特將學(xué)習(xí)過程記錄下來徙歼,供各位朋友參考,雖說是筆記灭翔,但是90%是書中內(nèi)容,另外10%是自己偶爾冒出的一點(diǎn)點(diǎn)想法的記錄和一些疑問煌张,希望互相探討萌狂。末尾有本章的代碼清單下載地址误趴,與各位交流冤留,還是提倡按照書中內(nèi)容把代碼一個(gè)個(gè)敲出來天通。
第四章 基本數(shù)據(jù)管理
本章內(nèi)容
操縱日期和缺失值
熟悉數(shù)據(jù)類型的轉(zhuǎn)換
變量的創(chuàng)建和重編碼
數(shù)據(jù)集的排序烘豹,合并與取子集
選入和丟棄變量
4.1 一個(gè)示例
代碼清單中,最后一行的最后一個(gè)參數(shù)憔鬼,stringsAsFactors = FALSE,個(gè)人認(rèn)為含義是:特征向量能否轉(zhuǎn)換為因子蚕愤,默認(rèn)TRUE,可以轉(zhuǎn)換砂沛。R中解釋為:
stringsAsFactors
logical: should character vectors be converted to factors? The ‘factory-fresh’ default is TRUE, but this can be changed by setting options(stringsAsFactors = FALSE)
4.2 創(chuàng)建新變量
在R中悟狱,算數(shù)運(yùn)算符除了+、-、*软免、/,還有
^(或 **):求冪。
x%%y:求余曹锨,5%%2的結(jié)果為1。
x%/%y:整數(shù)除法佳遂,5%/%2的結(jié)果為2。
代碼清單4-2提供了三種將新變量整合到原始的數(shù)據(jù)框中的方式吩屹。相當(dāng)于在列表中增加新的一列(新的觀測)唧席。作者推薦使用第三種方式迹卢,我個(gè)人也比較喜歡第三種腐碱,主要是簡便并且不容易誤操作殃饿。
4.3 變量的重編碼
重編碼涉及根據(jù)一個(gè)變量和/或其他變量的現(xiàn)有值創(chuàng)建新值得過程瓷们。
浮點(diǎn)型數(shù)據(jù)的概念和理解(百度百科)
P69頁的第一句話是什么意思?
語句variable[condition] <- expression將僅在condition的值為TRUE時(shí)執(zhí)行賦值攒钳。
解釋:
variable 變量的
condition 條件
expression 表達(dá)式
僅在變量的條件為TRUE時(shí)進(jìn)行賦值文兢。
首先要執(zhí)行“將99轉(zhuǎn)換為缺失值NA”,其次在書中P69頁執(zhí)行第一段或者第二段代碼。
函數(shù)within()與函數(shù)with()類似,不同的是它允許你修改數(shù)據(jù)框懂昂。
4.4變量的重命名
- 交互式方法榕吼。
使用fix(數(shù)據(jù)框名)即可調(diào)出一個(gè)交互式的編輯器,可直接點(diǎn)擊變量名進(jìn)行修改顽素。 - 編程的方法
下載胁出、載入reshape包寺枉,注意使用R 3.3.1版本始苇。然后使用其中的rename()函數(shù)即可函喉。
編程的方式也分為幾種方法:
直接將舊名稱換為新名稱哺窄。
data.frame <- rename(oldname = "newname", oldname = "newname", …)
指定變換的變量數(shù)字蔑担。
names(data.frame)[2] <- "newname"
以向量的方式批量更換某一部分變量名。
names(data.frame)[2:5] <- c("newname", "newname", …)
4.5 缺失值
is.na()將返回邏輯值TRUE(存在缺失值)和FALSE(不存在缺失值)。
注意:
缺失值被認(rèn)為是不可比較的蹲蒲,即便是與確實(shí)值自身的比較窍育。這一位這無法使用比較運(yùn)算符來檢測缺失值是否存在表锻。例如瞬逊,邏輯測試myvar == NA的結(jié)果永遠(yuǎn)不會是TRUE溶其。作為替代束铭,你只能使用處理缺失值的函數(shù)(如本節(jié)中所述的那些)來識別R數(shù)據(jù)對象終歸的缺失值。
4.5.1 重編碼某些值為缺失值
如4.3節(jié)那樣可以使用賦值語句將某些值重編碼為缺失值懈万。
leadership$age[leadership$age == 99] <- NA
請確保所有的缺失數(shù)據(jù)已在分析之前被妥善地編碼為缺失值会通,否則分析結(jié)果將失去意義。
4.5.2 在分析中排出缺失值
缺失值需要以某種方式刪除沪停,因?yàn)楹腥笔е档乃阈g(shù)表達(dá)式和函數(shù)的計(jì)算結(jié)果也是缺失值裳涛。
多數(shù)數(shù)值函數(shù)擁有一個(gè)na.rm = TRUE的選項(xiàng)端三,可以在計(jì)算之前移除缺失值并使用剩余值進(jìn)行計(jì)算。
x <- c(1, 2, NA, 3)
<BR>
y <- sum(x, na.rm = TRUE)
在使用函數(shù)處理不完整的數(shù)據(jù)時(shí)妻献,請務(wù)必查閱他們的幫助文檔旋奢,檢查這些函數(shù)是如何處理缺失數(shù)據(jù)的然痊。
函數(shù)na.omit()可以移除所有含有缺失值的觀測剧浸。
4.6 日期值
日期通常以字符串的方式輸入到R中唆香,然后轉(zhuǎn)化為以數(shù)值形式存儲的日期變量吨艇。函數(shù)as.Date()用于執(zhí)行這種轉(zhuǎn)化东涡。其語法為:as.Date(x, "input_format")
在P73頁中有一句話倘待,個(gè)人覺得凸舵,翻譯有誤失尖。原文為:
< 使用指定格式讀取字符型變量,并將其作為一個(gè)日期變量替換到數(shù)據(jù)框中菇夸。
個(gè)人建議將第二句話改為:并將其修改成指定格式的數(shù)值型變量(指定的日期格式)庄新。
時(shí)間戳
- Sys.Date()函數(shù) 返回當(dāng)天的日期邑商。
- date()函數(shù) 返回當(dāng)前的日期和時(shí)間童芹。
使用函數(shù)format(x, format = "output_format")來輸出指定格式的日期值胞此,并且可以提取日期值中的某些部分涩金。
疑問
在使用如下代碼時(shí)步做,書中顯示的是英文的非縮寫月份奈附,而在RStudio中是中文的月份斥滤。
today <- Sys.Date()
format(today, format = "%B %d %Y")
書中顯示的是:"December 01 2010"
而我操作時(shí)顯示的是:"六月 29 2016"
format(today, "%A")
書中顯示的是:"Wednesday"
而我操作時(shí)顯示的是:"星期三"
difftime()函數(shù)用于計(jì)算時(shí)間間隔,并以星期顶掉、天痒筒、時(shí)、分移袍、秒來表示萎战。units = auto(自動(dòng))蚂维、secs(秒)、mins(分)蔚约、hours(時(shí))涂籽、days(天)评雌、weeks(星期)。
問:為何沒有年為結(jié)果的參數(shù)選項(xiàng)砂轻?
4.6.1 將日期轉(zhuǎn)換為字符型變量
strDate <- as.character(dates)
4.6.2 更進(jìn)一步
要了解字符型數(shù)據(jù)轉(zhuǎn)換為日期的更多細(xì)節(jié)搔涝,請查看help(as.Date)和help(strftime)和措。
要了解更多關(guān)于日期和時(shí)間格式的知識派阱,請參考help(ISOdatetime)
lubridate包中包含了許多簡化日期處理的函數(shù),可以用于識別和解析日期-時(shí)間數(shù)據(jù)故响,抽取日期-時(shí)間成分(例如年份颁独、月份誓酒、日期等),以及對日期-時(shí)間值進(jìn)行算術(shù)運(yùn)算寨辩。
如果你需要對日期進(jìn)行復(fù)雜的計(jì)算靡狞,namefCalendar包可能會有幫助隔嫡。它提供了大量的日期處理函數(shù)腮恩,可以同時(shí)處理多個(gè)時(shí)區(qū),并且提供了歷法操作功能武契,支持工作日荡含、周末以及假期释液。
4.7 類型轉(zhuǎn)換
名為is.datatype()這樣的函數(shù)返回TRUE或FALSE均澳,而as.datatype()這樣的函數(shù)則將其參數(shù)轉(zhuǎn)換為對應(yīng)的類型。
4.8 數(shù)據(jù)排序
使用order()函數(shù)對一個(gè)數(shù)據(jù)框進(jìn)行排序糟袁。默認(rèn)的排序順序是升序躺盛,在排序變量前邊加一個(gè)減號槽惫,即可得到降序的排序結(jié)果界斜。order()可以同時(shí)添加多個(gè)變量。
4.9 數(shù)據(jù)集的合并
如果數(shù)據(jù)分散在多個(gè)地方项贺,你就需要在繼續(xù)下一步之前將其合并。本節(jié)展示了向數(shù)據(jù)框中添加列(變量)和行(觀測)的方法棕叫。
4.9.1 添加列
使用merge()函數(shù)可以俺泣,通過一個(gè)或多個(gè)共有變量合并數(shù)據(jù)框伏钠。
如下代碼
ID <- c(1, 2, 3)
name1 <- c("a", "b", "c")
age1 <- c(11, 12, 13)
name2 <- c("d", "e", "f")
age2 <- c(14, 15, 16)
dataframe1 <- data.frame(ID, name1, age1)
dataframe1
dataframe2 <- data.frame(ID, name2, age2)
dataframe2
newdataframe <- merge(dataframe1, dataframe2, by = "ID")
newdataframe
以上是通過一個(gè)共有變量ID坏怪,合并兩個(gè)數(shù)據(jù)框的铝宵。
newdataframe2 <- cbind(dataframe1, dataframe2)
newdataframe2
使用cbind()函數(shù)可以直接橫向合并兩個(gè)矩陣或數(shù)據(jù)框。
4.9.2 添加行
使用rbind()函數(shù)可以縱向合并兩個(gè)數(shù)據(jù)框(數(shù)據(jù)集)尊蚁。通常用于向數(shù)據(jù)框中添加觀測横朋。
注意
- 兩個(gè)數(shù)據(jù)框必須擁有相同的變量百拓,順序可以不同衙传。
- 如果數(shù)據(jù)框A中有數(shù)據(jù)框B沒有的變量蓖捶,請?jiān)诤喜⒅白鲆韵履撤N處理:
- 刪除A中的多余變量。
- 在B中創(chuàng)建追加的變量并將其值設(shè)為NA(缺失)刻像。
4.10 數(shù)據(jù)集取子集
R擁有強(qiáng)大的索引特性,可以用于訪問對象中的元素并闲。也可利用這些特性對變量或觀測進(jìn)行選入和排除细睡。
4.10.1 選入(保留)變量
myvars3 <- names(leadership) %in% c("q3", "q4")
newdata4 <- leadership[!myvars3]
newdata4
(1) names(leadership)生成了一個(gè)包含所有變量名的字符型向量:c("manafer", "date", "country", "gender", "age", "q1", "q2", "q3", "q4", "q5")。
〉刍稹(2) names(leadership) %in% c("q3", "q4")返回一個(gè)邏輯型向量纹冤,names(leadership)中每個(gè)匹配q3或q4的值為TRUE,反之為FALSE:c(FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, FALSE)洒宝。
(3)運(yùn)算符非(!)將邏輯值翻反轉(zhuǎn):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的列宏浩,于是q3和q4倍剔除了。
在知道q3和q4是第八個(gè)和第九個(gè)變量的情況下比庄,可以使用語句:
newdata <- leadership[c(-8, -9)]
將他們剔除求妹。原理是:**在某一列的下標(biāo)之前加一個(gè)減號(-)就會剔除那一列了。
相同的變量刪除工作亦可通過:
leadership$q3 <- leadershi$q4 <- NULL
來完成佳窑。
將q3和q4設(shè)為了未定義(NULL)制恍。注意,NULL和NA是不同的神凑。
4.10.3 選入觀測
選入或剔除觀測(行)通常是成功的數(shù)據(jù)準(zhǔn)備和數(shù)據(jù)分析的一個(gè)關(guān)鍵方面净神。
代碼清單4-6 選入觀測
newdata <- leadership[1:3, ]
newdata
newdata <- leadership[which(leadership$gender == "M" & leadership$age > 30), ]
newdata
attach(leadership)
newdata <- leadership[which(gender == "M"& leadership$age > 30), ]
detach(leadership)
newdata
在以上的每個(gè)示例中,你只提供了行下標(biāo)溉委,并將列下標(biāo)留空(故選入了所有列)鹃唯。在第一個(gè)示例中,你選擇了第一行到第三行(前三個(gè)觀測)瓣喊。
在第二個(gè)示例中坡慌,你選擇了所有30歲以上的男性。讓我們拆解這行代碼以便理解它藻三。
(1) 邏輯比較leadership$gender == "M" 生成了向量c(TRUE, FALSE, FALSE, TRUE, FALSE)洪橘。
(2) 邏輯比較leadership$age > 30 生成了向量c(TRUE, TRUE, FALSE, TRUE, TRUE)。
(3) 邏輯比較c(TRUE, FALSE, FALSE, TRUE, FALSE) & c(TRUE, TRUE, FALSE, TRUE, TRUE)生成了向量c(TRUE, FALSE, FALSE, TRUE, FALSE)棵帽。
(4) 函數(shù)which()給出了向量中值為TRUE元素的下標(biāo)熄求。因此,which(c(TRUE, FALSE, FALSE, TRUE, FALSE))生成了向量c(1, 4)岖寞。
(5) leadership[c(1, 4), ]從數(shù)據(jù)框中選擇了第一個(gè)和第四個(gè)觀測抡四。這就滿足了我們選取準(zhǔn)則(30歲以上的男性)。
第三個(gè)示例使用了attach()函數(shù)仗谆,所以就不必再變量名前加上數(shù)據(jù)框名稱了指巡。
將研究范圍限定子啊2009年1月1日到2009年12月31日之間收集的觀測,使用以下代碼:
leadership$date <- as.Date(leadership$date, "%m/%d/%y")
startdate <- as.Date("2009-01-01")
enddate <- as.Date("2009-12-31")
newdate <- leadership[wihch(leadershi$date >= startdate & leadership$date <= enddate), ]
4.10.4 subset()函數(shù)
使用subset()函數(shù)可以簡便的選入觀測隶垮。
冒號運(yùn)算符“:”藻雪,表示從…到…,在書中表示選擇保留的列狸吞。
4.10.5 隨機(jī)抽樣
sample()函數(shù)可以從數(shù)據(jù)集中(有放回或無放回地)抽取大小為n的一個(gè)隨機(jī)樣本勉耀。
sample()函數(shù)中的第一個(gè)參數(shù)是一個(gè)由要從中抽樣的元素組成的向量指煎,在這里,這個(gè)向量是1到數(shù)據(jù)框中觀測的梳理便斥,第二個(gè)參數(shù)是要抽取的元素?cái)?shù)量至壤,第三個(gè)參數(shù)表示無放回抽樣。sample()函數(shù)會返回隨機(jī)抽樣得到的元素枢纠,之后可用于選擇數(shù)據(jù)框中的行像街。
更進(jìn)一步
R中擁有齊全的抽樣工具,包括抽取和小鄭調(diào)查樣本(詳見sampling包)以及分析復(fù)雜調(diào)查數(shù)據(jù)(詳見survey包)的工具其他依賴于抽樣的方法晋渺,包括自助法和重抽樣統(tǒng)計(jì)方法镰绎,詳見第11章。
4.11 使用SQL語句操作數(shù)據(jù)框
由于不會SQL以及沒有數(shù)據(jù)庫相關(guān)經(jīng)驗(yàn)木西,故跳過此章畴栖。