項(xiàng)目二、玩撲克牌
第三章 R對(duì)象
3.1 原子型向量(atomic vector)
在項(xiàng)目一中我們生成的die
就是一個(gè)原子型向量
die <- c(1,2,3,4,5,6);die
## 1 2 3 4 5 6
is.vector(die) #該函數(shù)表示測(cè)試某對(duì)象是否為原子型向量蛔外,是返回TRUE蛆楞,否FALSE
## TRUE
length(die) #返回原子型向量的長(zhǎng)度
## 6
R可以識(shí)別六種基本類型的原子型向量,分別是:雙整型(double)夹厌、整型(integer)豹爹、字符型(character)、邏輯型(logical)矛纹、復(fù)數(shù)類型(complex)臂聋、原始類型(raw)
3.1.1 雙整型
die <- c(1,2,3,4,5,6);die #die就是一個(gè)雙整型向量
## 1 2 3 4 5 6
typeof(die) # 該函數(shù)可以返回向量的類型
## "double"
class(die) # 該函數(shù)可以返回向量的類型
## "numeric"
我們可以看到同樣是查看對(duì)象類型但typeof
返回的是雙整型,class
返回的是numeric
(數(shù)值型)。這其實(shí)是一類孩等,只是不同的稱呼艾君。雙整型是計(jì)算機(jī)科學(xué)的術(shù)語(yǔ),但在數(shù)據(jù)科學(xué)肄方,數(shù)值型更符合我們的邏輯冰垄。
3.1.2 整型
顧名思義,整型數(shù)據(jù)的數(shù)值不需要小數(shù)點(diǎn)成分权她。我們分析數(shù)據(jù)用不到這種類型的向量虹茶。這里解釋下其與雙整型的異同。
# 在R中明確設(shè)定整型的方法是在數(shù)值后加上大寫字母L隅要,否則R自動(dòng)存儲(chǔ)為雙整型
int <- c(-1L, 2L, 3L); int
## -1 2 3
typeof(int)
## "integer"
那為什么要把數(shù)據(jù)存儲(chǔ)為整型而不是雙整型吶蝴罪?我們用個(gè)例子來(lái)看下
sqrt(2)^2 - 2 # 提示:sqrt是平方根(square root)的意思,R中許多函數(shù)名字都是其英文的縮寫拾徙,所以記憶這些函數(shù)還是有規(guī)律可循的~
## 4.440892e-16
round(sqrt(2)^2)-2 #函數(shù)round代表四舍五入取整
## 0
按我們正常思考上述結(jié)果都應(yīng)該為0洲炊,但卻不是,這是因?yàn)橛?jì)算機(jī)給雙整型對(duì)象分配64字節(jié)即可以精確到小數(shù)點(diǎn)后16位尼啡,根號(hào)2是無(wú)限不循環(huán)小數(shù)暂衡,計(jì)算機(jī)只能保留至小數(shù)點(diǎn)后16位,所以出現(xiàn)了上述的結(jié)果崖瞭。這樣的舍入誤差也叫做浮點(diǎn)(floating-point)誤差狂巢,這種情況下的運(yùn)算叫做浮點(diǎn)運(yùn)算。
3.1.3 字符型
字符加上雙引號(hào)书聚,再組合起來(lái)構(gòu)成一個(gè)字符型向量唧领。字符型向量中的單個(gè)元素稱為字符串(string)
text <- c("Hello", "World")
text
## "Hello" "World"
typeof(text)
## "character"
typeof("Hello")
## "character"
一定記住字符串在鍵入和操作時(shí)加上雙引號(hào)("")
3.1.4 邏輯型
存儲(chǔ)TRUE
和FALSE
是R中布爾數(shù)據(jù)的表現(xiàn)形式。在比對(duì)數(shù)據(jù)時(shí)雌续,邏輯型非常有用斩个!
3 > 4
## FALSE
logic <- c(TRUE, FALSE, TRUE)
logic
## TRUE FALSE TRUE
typeof(logic)
## "logical"
typeof(F) # R會(huì)默認(rèn)把T和F當(dāng)作TRUE和FALSE的簡(jiǎn)寫
## "logical"
3.1.5 復(fù)數(shù)類型和原始類型
分析數(shù)據(jù)基本用不到這兩種類型,此處就不介紹了~
3.2 屬性
屬性是附加給原子型向量的額外信息驯杜,可以將屬性賦予任意一個(gè)R對(duì)象
attributes(die) #因?yàn)閐ie沒(méi)有任何屬性所以返回NULL受啥,意思就是空值
## NULL
一個(gè)原子型向量最常見的三種屬性是:名稱(name)、維度(dim)和類(class)
3.2.1 名稱屬性
利用names()函數(shù)給die
賦予名稱屬性鸽心,這個(gè)字符向量的長(zhǎng)度要與die
等長(zhǎng)
names(die) <- c("one", "two", "three", "four", "five", "six")
names(die)
## "one" "two" "three" "four" "five" "six"
attributes(die)
## $names
## [1] "one" "two" "three" "four" "five" "six"
die # 我們可以發(fā)現(xiàn)顯示die向量時(shí)滚局,名稱屬性出現(xiàn)在了對(duì)應(yīng)元素上方
## one two three four five six
## 1 2 3 4 5 6
die + 1 # 但名稱并不會(huì)對(duì)向量中的實(shí)際值產(chǎn)生影響,比如向量+1顽频,名稱不會(huì)變的藤肢。
## one two three four five six
## 2 3 4 5 6 7
# 可以使用names()函數(shù)對(duì)名稱屬性批量修改或刪除
names(die) <- c("uno", "dos", "tres", "quatro", "cinco", "seis")
die
## uno dos tres quatro cinco seis
## 1 2 3 4 5 6
# 刪除名稱屬性值,只需將NULL賦予names函數(shù)
names(die) <- NULL
die
## 1 2 3 4 5 6
3.2.2 維度屬性
原理同上糯景,使用dim()
函數(shù)即可
dim(die) <- c(2,3); die
## [,1] [,2] [,3]
## [1,] 1 3 5
## [2,] 2 4 6
3.3 矩陣
m <- matrix(die, nrow = 2)
m
## [,1] [,2] [,3]
## [1,] 1 3 5
## [2,] 2 4 6
m <- matrix(die, nrow = 2, byrow = TRUE) # 上面結(jié)果可見R默認(rèn)按列進(jìn)行數(shù)據(jù)填充嘁圈,這個(gè)參數(shù)byrow = TRUE代表按行填充
m
## [,1] [,2] [,3]
## [1,] 1 2 3
## [2,] 4 5 6
3.4 數(shù)組
array
函數(shù)生成一個(gè)n維數(shù)組
args(array) # 查看array函數(shù)的參數(shù)省骂,發(fā)現(xiàn)只有3個(gè)
## function (data = NA, dim = length(data), dimnames = NULL)
# 利用arry創(chuàng)建一個(gè)三維數(shù)組
ar = array(c(11:14, 21:24, 31:34),dim = c(2,2,3));ar #2行2列3個(gè)切面
## , , 1
##
## [,1] [,2]
## [1,] 11 13
## [2,] 12 14
## , , 2
## [,1] [,2]
## [1,] 21 23
## [2,] 22 24
## , , 3
## [,1] [,2]
## [1,] 31 33
## [2,] 32 34
練習(xí)題:生成撲克牌矩陣
hand <- matrix(c("ace","king","queen","jack","ten",rep("spades",5)),
nrow = 5)
hand
## [,1] [,2]
## [1,] "ace" "spades"
## [2,] "king" "spades"
## [3,] "queen" "spades"
## [4,] "jack" "spades"
## [5,] "ten" "spades"
3.5 類
更改對(duì)象的維度并不會(huì)改變其類型,但會(huì)改變這個(gè)對(duì)象的class屬性
die <- c(1,2,3,4,5,6)
typeof(die)
## "double"
class(die)
## "numeric"
dim(die) <- c(2,3)
typeof(die)
## "double"
class(die)
## "matrix"
運(yùn)行attributes函數(shù)時(shí)最住,對(duì)象的class屬性并非總是會(huì)顯示冀宴,可以使用class函數(shù)專門搜索對(duì)象的class屬性
die <- c(1,2,3,4,5,6)
dim(die) <- c(2,3)
attributes(die)
## $dim
## [1] 2 3
class(die)
## "matrix"
3.5.1 日期與時(shí)間
除了雙整型、整型温学、字符型、邏輯型甚疟、復(fù)數(shù)類型和原始類型外仗岖,R的屬性系統(tǒng)還能表示更多的數(shù)據(jù)類型。下面我們來(lái)了解下
now <- Sys.time() #該函數(shù)的目的是返回當(dāng)前計(jì)算機(jī)的時(shí)間
now
## "2021-04-16 21:55:42 CST"
typeof(now)
## "double"
class(now)
## "POSIXct" "POSIXt"
沒(méi)錯(cuò)览妖,返回的感覺(jué)是一個(gè)字符串轧拄,但它的類型是雙整型,它的類是POSIXct和POSIXt讽膏。POSIXct是一個(gè)廣泛用于表示日期與時(shí)間的框架檩电。在POSIXct框架下,使勁按被表示為自1970年1月1日零點(diǎn)(UTC時(shí)間)開始逝去的秒數(shù)府树。比如剛剛我電腦的時(shí)間相對(duì)這個(gè)時(shí)間已經(jīng)過(guò)去了1618581342秒俐末,因此在POSIXct下被存儲(chǔ)為數(shù)值1618581342,所以typeof()
返回的是雙整型奄侠。
R用單個(gè)元素1618581342的雙整型向量生成了一個(gè)時(shí)間對(duì)象卓箫,為了看到這個(gè)向量的本來(lái)面目,我們可以把事件對(duì)象now的class屬性移除垄潮。
unclass(now)
## 1618581342
這就很有趣烹卒,給一個(gè)雙整型向量,然后R會(huì)將一個(gè)包含兩個(gè)類(POSIXct和POSIXt)的class屬性賦給該雙整型向量弯洗,此屬性提醒R旅急,正在處理POSIXct時(shí)間,應(yīng)以特殊方式處理牡整,即返回給我們可以理解的字符串形式
second <- 1234567
second
## 1234567
class(second) <- c("POSIXct", "POSIXt")
second
## "1970-01-15 14:56:07 CST"
至此我們知道R中其實(shí)很有特殊的類(class)藐吮。如果需要詳細(xì)了解某個(gè)類時(shí)查看其幫助文檔即可
3.5.2 因子
因子在R中用來(lái)存儲(chǔ)分類信息,我們可以把因子視為性別類似的概念果正;它只可以去某些特定的值(男性或女性)炎码,而這些值之間可能有一些特殊的順序規(guī)定(比如女士?jī)?yōu)先)。該特性非常適合記錄分類變量如腫瘤秋泳、非腫瘤潦闲。
gender <- factor(c('male','female','female','male'))
typeof(gender) #R會(huì)將向量中的值重新編碼為一串整數(shù)值并存儲(chǔ)在一個(gè)整型向量中
## "integer"
attributes(gender)
## $levels
## [1] "female" "male"
## $class
## [1] "factor"
unclass(gender) # unclass函數(shù),可以看R到底如何存儲(chǔ)因子的
## [1] 2 1 1 2
## attr(,"levels")
## [1] "female" "male"
gender #R顯示因子因子時(shí)用了levels屬性迫皱,即1顯示為female歉闰,2顯示為male
## [1] male female female male
## Levels: female male
上述結(jié)果可見辖众,向factor
函數(shù)賦值一個(gè)向量可生成因子步悠。R會(huì)將向量中的值重新編碼為一串整數(shù)值并存儲(chǔ)在一個(gè)整型向量中生闲。此外R還會(huì)將一個(gè)levels屬性和一個(gè)class屬性添加到該整型向量中,levels
屬性包含顯示因子值的一組標(biāo)簽懒熙,而class
屬性包含類:factor昼弟。
因子的存在啤它,使統(tǒng)計(jì)模型中加入分類變量很簡(jiǎn)單,因?yàn)檫@些分類變量已經(jīng)被編碼成一些數(shù)值舱痘。
as.character(gender) #強(qiáng)制將因子轉(zhuǎn)換為字符串
## "male" "female" "female" "male"
3.6 強(qiáng)制轉(zhuǎn)換
向量变骡、矩陣、數(shù)值均只能存儲(chǔ)單一類型數(shù)據(jù):字符串型>數(shù)值型>邏輯型
a <- c(1,“TRUE”)
a
## “1” “TRUE”
b <- c(1,TRUE) #邏輯型中默認(rèn)TRUE=1, FALSE=0
b
## 1 1
sum(c(TRUE,TRUE,FALSE,FALSE)) #會(huì)變成sum(c(1,1,0,0))芭逝,就是計(jì)算包含幾個(gè)TRUE值
## 2
mean(c(TRUE,TRUE,FALSE,FALSE)) #mean函數(shù)計(jì)算TRUE值所占比例
## 0.5
類型之間強(qiáng)制轉(zhuǎn)換需要用到as
系列函數(shù)
as.character(1)
## "1"
as.logical(1)
## TRUE
as.numeric(FALSE)
## 0
3.7 列表
一維集合塌碌,列表將某些具體的值組織起來(lái),而是組織R對(duì)象
list1 <- list(100:130, "R", list(TRUE, FALSE))
list1
## [[1]]
## [1] 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117
## [19] 118 119 120 121 122 123 124 125 126 127 128 129 130
## [[2]]
## [1] "R"
## [[3]]
## [[3]][[1]]
## [1] TRUE
## [[3]][[2]]
## [1] FALSE
[[]]
代表來(lái)自列表中的第幾個(gè)元素旬盯,[]
代表來(lái)著這個(gè)元素的哪一個(gè)子元素台妆。
練習(xí):創(chuàng)建點(diǎn)數(shù)為1的紅桃A
card <- list('ace', 'hearts', 1)
card
## [[1]]
## [1] "ace"
## [[2]]
## [1] "hearts"
## [[3]]
## [1] 1
3.8 數(shù)據(jù)框
數(shù)據(jù)庫(kù)是列表的二維版本,重點(diǎn):數(shù)據(jù)框以列為單位組織數(shù)據(jù)胖翰。不同列可以包含不同的數(shù)據(jù)類型接剩。但數(shù)據(jù)框中的每一列都必須具有相同的長(zhǎng)度。
df <- data.frame(face = c("ace", "two", "six"),
suit = c("clubs", "clubs", "clubs"),
value = c(1, 2, 3))# 需確保每個(gè)向量長(zhǎng)度相等泡态,face搂漠,suit,value均為對(duì)象的names屬性
df
## face suit value
## ace clubs 1
## two clubs 2
## six clubs 3
此時(shí)我們查看df
的類型會(huì)發(fā)現(xiàn)是一個(gè)列表某弦,class
屬性為數(shù)據(jù)框桐汤,實(shí)際上,每個(gè)數(shù)據(jù)框都有一個(gè)具有data.frame類的列表靶壮≌可以用str
函數(shù)查看這個(gè)列表或者數(shù)據(jù)框中,哪些對(duì)象被組織到一起了
typeof(df)
## "list"
class(df)
## "data.frame"
str(df)
## 'data.frame': 3 obs. of 3 variables:
## $ face : Factor w/ 3 levels "ace","six","two": 1 3 2
## $ suit : Factor w/ 1 level "clubs": 1 1 1
## $ value: num 1 2 3
重點(diǎn)L诮怠<鸲取!我們發(fā)現(xiàn)R將字符串存儲(chǔ)成了因子(因?yàn)椴蛔鎏厥馓幚鞷就會(huì)自動(dòng)這樣做)螃壤。加上這行命令即可實(shí)現(xiàn)字符串形式存儲(chǔ)
options(stringsAsFactors = FALSE)
df <- data.frame(face = c("ace", "two", "six"),
suit = c("clubs", "clubs", "clubs"),
value = c(1, 2, 3))
str(df)
## 'data.frame': 3 obs. of 3 variables:
## $ face : chr "ace" "two" "six"
## $ suit : chr "clubs" "clubs" "clubs"
## $ value: num 1 2 3
至此我們可以利用數(shù)據(jù)框來(lái)生成一副撲克牌
deck <- data.frame(
face = c("king", "queen", "jack", "ten", "nine", "eight", "seven", "six",
"five", "four", "three", "two", "ace", "king", "queen", "jack", "ten",
"nine", "eight", "seven", "six", "five", "four", "three", "two", "ace",
"king", "queen", "jack", "ten", "nine", "eight", "seven", "six", "five",
"four", "three", "two", "ace", "king", "queen", "jack", "ten", "nine",
"eight", "seven", "six", "five", "four", "three", "two", "ace"),
suit = c("spades", "spades", "spades", "spades", "spades", "spades",
"spades", "spades", "spades", "spades", "spades", "spades", "spades",
"clubs", "clubs", "clubs", "clubs", "clubs", "clubs", "clubs", "clubs",
"clubs", "clubs", "clubs", "clubs", "clubs", "diamonds", "diamonds",
"diamonds", "diamonds", "diamonds", "diamonds", "diamonds", "diamonds",
"diamonds", "diamonds", "diamonds", "diamonds", "diamonds", "hearts",
"hearts", "hearts", "hearts", "hearts", "hearts", "hearts", "hearts",
"hearts", "hearts", "hearts", "hearts", "hearts"),
value = c(13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1)
)
deck
## face suit value
## 1 king spades 13
## 2 queen spades 12
## 3 jack spades 11
## 4 ten spades 10
## 5 nine spades 9
## 6 eight spades 8
## 7 seven spades 7
## 8 six spades 6
## 9 five spades 5
## 10 four spades 4
## 等等
但每次想生成撲克牌都輸入這么多的數(shù)據(jù)抗果,非常繁瑣且易出錯(cuò),所以我們可以把這個(gè)數(shù)據(jù)存儲(chǔ)為文件奸晴,用的時(shí)候讀取即可冤馏。
3.9 保存和讀取數(shù)據(jù)
write.csv(deck,file = 'deck.csv', row.names = F) #保存deck數(shù)據(jù)框,文件命名為deck.csv寄啼,不保存行名
deck <- read.csv('deck.csv',header = T)
head(deck) #查看前6行
## face suit value
## king spades 13
## queen spades 12
## jack spades 11
## ten spades 10
## nine spades 9
## eight spades 8
tail(deck) #查看最后6行
tail(deck, 10)#查看最后10行
3.10 總結(jié)
R中最常用的數(shù)據(jù)結(jié)構(gòu)為向量逮光、矩陣代箭、數(shù)組、列表和數(shù)據(jù)框涕刚。注意區(qū)分他們的異同嗡综。