第四章
本章內(nèi)容:
- 操作日期和缺失值
- 熟悉數(shù)據(jù)類型的轉(zhuǎn)換
- 變量的創(chuàng)建和重編碼
- 數(shù)據(jù)集的排序、合并與取子集
- 選入和丟棄變量
4.1 一個(gè)示例
新建示例(示例具體含義大家可以看下R語(yǔ)言實(shí)戰(zhàn)第2版p69):
| 經(jīng)理人 | 日期 | 國(guó)籍 | 性別 | 年齡 | q1 | q2 | q3 | q4 | q5 |
|---|---|---|---|---|---|---|---|---|---|
| 1 | 10/24/08 | US | M | 32 | 5 | 4 | 5 | 5 | 5 |
| 2 | 10/28/08 | US | F | 45 | 3 | 5 | 2 | 5 | 5 |
| 3 | 10/01/08 | UK | F | 25 | 3 | 5 | 5 | 5 | 2 |
| 4 | 10/12/08 | UK | M | 39 | 3 | 3 | 4 | ||
| 5 | 05/01/09 | UK | F | 99 | 2 | 2 | 1 | 2 | 1 |
使用代碼創(chuàng)建一個(gè)名為leadership的數(shù)據(jù)框存儲(chǔ)上述表格
manager <- c(1,2,3,4,5)
data <- c('10/24/08','10/28/08','10/01/08','10/12/08','05/01/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, data, country, gender, age,q1,q2,q3,q4,q5,
stringsAsFactors = FALSE)
4.2 創(chuàng)建新變量
公式:
變量名 <- 表達(dá)式
“表達(dá)式”可以包含多種運(yùn)算符和函數(shù)。
給數(shù)據(jù)框mydata添加兩個(gè)變量,x1x2之和,x1x2的平均數(shù)
mydata <- data.frame(x1 = c(2,2,6,4),
x2 = c(3,4,2,8))
# 方法一
mydata$sum <- mydata$x1 + mydata$x2
mydata$mean <- (mydata$x1 + mydata$x2)/2
# 方法二
attach(mydata)
sum <- x1 + x2
mean <- (x1 + x2)/2
detach(mydata)
# 方法三
mydata <- transform(mydata, sum = x1 + x2,
mean = (x1+x2)/2)
推薦大家使用方法三,簡(jiǎn)單快捷
4.3 變量的重編碼
重編碼涉及根據(jù)同一變量和或其他變量的現(xiàn)有值創(chuàng)建新值的過(guò)程。
不妨假設(shè)你希望將leadership數(shù)據(jù)集中經(jīng)理人的連續(xù)型年齡變量age重編碼為類別型變量agecat(Young、 Middle Aged、Elder)。首先,必須將99歲的年齡值重編碼為缺失值(因?yàn)椴豢赡苡腥?9歲了還當(dāng)經(jīng)理,我們默認(rèn)99是缺失值),使用的代碼為:
leadership$age[leadership$age == 99] <- NA
然后用以下代碼創(chuàng)建新變量agecat為age的類別型變量
leadership$agecut[leadership$age > 60] <- "Elder"
leadership$agecut[leadership$age >= 40 &
leadership$age <= 60] <- "Middle Aged"
leadership$agecut[leadership$age < 40 ] <- "Young"
當(dāng)然這個(gè)代碼看起來(lái)很臃腫,可以用函數(shù)within()它和with()
類似,不同的就是函數(shù)within()可以允許你修改數(shù)據(jù)。
leadership <- within(leadership,{
agecut <- NA
agecut[age>60] <- 'Elder'
agecut[age>=40 & age<=60] <- 'Middle Aged'
agecut[age<40] <- 'Young'
})
此時(shí)agecut只是字符型變量,我們需要轉(zhuǎn)換成有序型因子:
leadership$agecut <- factor(leadership$agecut,
levels = c('Young','Middle Aged','Elder'),
ordered = TRUE)
4.4 變量的重命名
方法一:
names(leadership)[1] <- "ManageID"
names(leadership)[2] <- "testDate"
方法二:使用plyr包中的函數(shù)rename()
使用格式:
rename(dataframe,c(oldname = 'newname', oldname = 'newname', ...))
install.packages("plyr") #已經(jīng)安裝了plyr包的略過(guò)這一步
library(plyr)
leadership <- rename(leadership,
c(manager = "ManageID",
date = "testData"))
4.5 缺失值
is.na()檢測(cè)缺失值是否存在。
is.na(leadership[,6:10])
## q1 q2 q3 q4 q5
## [1,] FALSE FALSE FALSE FALSE FALSE
## [2,] FALSE FALSE FALSE FALSE FALSE
## [3,] FALSE FALSE FALSE FALSE FALSE
## [4,] FALSE FALSE FALSE TRUE TRUE
## [5,] FALSE FALSE FALSE FALSE FALSE
檢測(cè)數(shù)據(jù)框leadership第6-10列是否有缺失值
注意:
- 缺失值被認(rèn)為是不可比較的。
- R并不會(huì)把無(wú)限的或者不可能出現(xiàn)的標(biāo)記為缺失值。正無(wú)窮和負(fù)無(wú)窮分別為
Inf和-Inf,不可能的值用NaN表示。識(shí)別分別用is.infinite()或is.nan()
4.5.1 重編碼某些值為缺失值
leadership$age[leadership$age == 99] <- NA
4.5.2 在分析中排除缺失值
很多函數(shù)自帶參數(shù)na.rm = TRUE,可以在計(jì)算之前移除缺失值使用剩余值計(jì)算
x = c(1,2,NA,4)
sum(x, na.rm = TRUE)
使用函數(shù)處理不完整的數(shù)據(jù)時(shí),查下幫助文檔,看看這些函數(shù)時(shí)如何處理缺失數(shù)據(jù)的。
na.omit()移除所有含缺失值的觀測(cè)。
(newdata = na.omit(leadership))
## ManageID testData country gender age q1 q2 q3 q4 q5 agecut
## 1 1 2008-10-24 US M 32 5 4 5 5 5 Young
## 2 2 2008-10-28 US F 45 3 5 2 5 5 Middle Aged
## 3 3 2008-10-01 UK F 25 3 5 5 5 2 Young
4.6 日期值
日期值通常以字符串的形式輸入到R中,然后轉(zhuǎn)化為以數(shù)值形式存儲(chǔ)的日期變量。語(yǔ)法as.Data(x, "input_format")
日期格式如下表
| 符號(hào) | 含義 | 示例 |
|---|---|---|
| %d | 數(shù)字表示的日期(0~31) | 01~31 |
| %a | 縮寫的星期名 | Mon |
| %A | 非縮寫星期名 | Monday |
| %m | 月份(00~12) | 00~12 |
| %b | 縮寫的月份 | Jan |
| %B | 非縮寫月份 | January |
| %y | 兩位數(shù)的年份 | 07 |
| %Y | 四位數(shù)的年份 | 2007 |
日期值默認(rèn)輸入格式為‘yyyy-mm-dd’
Sys.Date() #返回當(dāng)前日期
## "2021-05-25"
Sys.time() #返回當(dāng)前日期+時(shí)間
## "2021-05-25 16:44:31 CST"
使用format(x, format = "output_format")來(lái)輸出指定格式的日期值或提取日期值的某些部分
today = Sys.Date()
format(today, format = "%d/%m/%y")
## "25/05/21"
format(today, format = "%A")
## "星期二"
既然存儲(chǔ)為了數(shù)值型數(shù)據(jù),那日期是可以進(jìn)行算術(shù)運(yùn)算的
today = Sys.Date()
my_birth <- as.Date("1996-01-11")
days <- today - my_birth
days
## Time difference of 9266 days
函數(shù)difftime()可以來(lái)計(jì)算時(shí)間間隔,并以星期、天、時(shí)、分、秒來(lái)表示(取決于參數(shù)units =)。
difftime(today, my_birth, units = "weeks")
## Time difference of 1323.714 weeks
思考下大家可以知道m(xù)y_birth這一天是周幾嗎?
format(my_birth, "%A")
## "星期四"
4.6.1 將日期轉(zhuǎn)換為字符型變量
strdata = as.character(data)
# 舉例
as.character(my_birth)
## "1996-01-11"
4.7 類型轉(zhuǎn)換
類型轉(zhuǎn)換函數(shù)
| 判斷 | 轉(zhuǎn)換 |
|---|---|
| is.numeric() | as.numeric() |
| is.character() | as.character() |
| is.vector() | as.vector() |
| is.matrix() | as.matrix() |
| is.data.frame() | as.data.frame() |
| is.factor() | as.factor() |
| is.logical() | as.logical() |
4.8 數(shù)據(jù)排序
order()默認(rèn)升序,在排序變量的前邊加一個(gè)減號(hào)即可得到降序的排序結(jié)果。
舉例:各行依女性到男性、同樣性別中按年齡升序排序。
newdata <- leadership[order(leadership$gender,leadership$age),]
各行依女性到男性、同樣性別中按年齡降序排序。
newdata <- leadership[order(leadership$gender, -leadership$age),]
4.9 數(shù)據(jù)集的合并
方法一:
橫向合并兩個(gè)數(shù)據(jù)框
total = merge(dataframeA, dataframeB, by = "ID")
將dataframeA和dataframeB按ID進(jìn)行合并。
total = merge(dataframeA, dataframeB, by = c("ID","Country"))
將dataframeA和dataframeB按ID和Country進(jìn)行合并。
方法二:
cbind()
橫向合并,保證其正常工作需:每個(gè)對(duì)象必須擁有相同的行數(shù)、以同順序排序。
方法三:
rbind()
total = rbind(dataframeA, dataframeB)
4.10 數(shù)據(jù)集取子集
4.10.1 選入(保留)變量
myvars <- paste0("q",1:5)
newdata <- leadership[myvars]
newdata2 <- leadership[,myvars]
newdata=newdata2保留q1-q5列
4.10.2 剔除(丟棄)變量
方法一:
myvar <- names(leadership) %in% c("q1","q2")
newdata <- leadership[!myvar]
newdata
方法二:只要要?jiǎng)h哪一行,直接給出來(lái)即可
newdata <- leadership[c(-6,-7)]
方法三:知道要?jiǎng)h哪個(gè)變量,直接賦值NULL
leadership$q1 = leadership$q2 = NULL
4.10.3 選入觀測(cè)
舉例:選出30歲以上的男性
select1 <- leadership[leadership$gender == 'M' & leadership$age > 30,]
研究范圍限定在在2009年1月1日到2009年12月31日之間收集的觀測(cè)上
min <- as.Date("2009-01-01")
max <- as.Date("2009-12-31")
select2 <- leadership[leadership$data > min & leadership$data < max,]
4.10.4 subset()函數(shù)
非常簡(jiǎn)單的選擇變量和觀測(cè)的方法
select3 <- subset(leadership, age>=35|age<24,
select = c(q1:q4))
第一個(gè)參數(shù):要進(jìn)行篩選的數(shù)據(jù)集
第二個(gè)參數(shù):邏輯表達(dá)式—表示要留下的行(此處為留下年齡在24-35的人)
第三個(gè)參數(shù):要留下的列(此處為留下q1-q4列)
4.10.5 隨機(jī)抽樣
select4 <- leadership[sample(1:nrow(leadership), 3, replace = FALSE),]
在數(shù)據(jù)挖掘和機(jī)械學(xué)習(xí)中常用。如你可能希望選擇兩份隨機(jī)樣本,一份用于構(gòu)建預(yù)測(cè)模型,另一份用于驗(yàn)證模型的有效性。
小結(jié)
1、掌握創(chuàng)建新變量的函數(shù)transform(mydata, name1 = value1, name2 = value2, ...)。
2、掌握within()與with()用法相似,不同點(diǎn)在于可以對(duì)變量進(jìn)行修改。
3、掌握rename(dataframe,c(oldname = 'newname', oldname = 'newname', ...))。對(duì)變量重命名。
4、掌握函數(shù)merge()和subset()