R語(yǔ)言實(shí)戰(zhàn)第4章:基本數(shù)據(jù)管理

第四章

本章內(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列是否有缺失值
注意:

  1. 缺失值被認(rèn)為是不可比較的。
  2. 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()

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容