R语言入门与实践笔记(第三章)

项目二、玩扑克牌

第三章 R对象

3.1 原子型向量(atomic vector)

在项目一中我们生成的die就是一个原子型向量

die <- c(1,2,3,4,5,6);die
## 1 2 3 4 5 6

is.vector(die) #该函数表示测试某对象是否为原子型向量,是返回TRUE,否FALSE
## TRUE

length(die) #返回原子型向量的长度
## 6

R可以识别六种基本类型的原子型向量,分别是:双整型(double)、整型(integer)、字符型(character)、逻辑型(logical)、复数类型(complex)、原始类型(raw)

3.1.1 双整型
die <- c(1,2,3,4,5,6);die #die就是一个双整型向量
## 1 2 3 4 5 6

typeof(die) # 该函数可以返回向量的类型
##  "double"

class(die) # 该函数可以返回向量的类型
##  "numeric"

我们可以看到同样是查看对象类型但typeof返回的是双整型,class返回的是numeric(数值型)。这其实是一类,只是不同的称呼。双整型是计算机科学的术语,但在数据科学,数值型更符合我们的逻辑。

3.1.2 整型

顾名思义,整型数据的数值不需要小数点成分。我们分析数据用不到这种类型的向量。这里解释下其与双整型的异同。

# 在R中明确设定整型的方法是在数值后加上大写字母L,否则R自动存储为双整型
int <- c(-1L, 2L, 3L); int
##  -1  2  3

typeof(int)
##  "integer"

那为什么要把数据存储为整型而不是双整型呐?我们用个例子来看下

sqrt(2)^2 - 2 # 提示:sqrt是平方根(square root)的意思,R中许多函数名字都是其英文的缩写,所以记忆这些函数还是有规律可循的~
## 4.440892e-16

round(sqrt(2)^2)-2 #函数round代表四舍五入取整
##  0

按我们正常思考上述结果都应该为0,但却不是,这是因为计算机给双整型对象分配64字节即可以精确到小数点后16位,根号2是无限不循环小数,计算机只能保留至小数点后16位,所以出现了上述的结果。这样的舍入误差也叫做浮点(floating-point)误差,这种情况下的运算叫做浮点运算

3.1.3 字符型

字符加上双引号,再组合起来构成一个字符型向量。字符型向量中的单个元素称为字符串(string)

text <- c("Hello", "World") 
text
##  "Hello" "World"

typeof(text)
## "character"

typeof("Hello")
## "character"

一定记住字符串在键入和操作时加上双引号("")

3.1.4 逻辑型

存储TRUEFALSE是R中布尔数据的表现形式。在比对数据时,逻辑型非常有用!

3 > 4
## FALSE

logic <- c(TRUE, FALSE, TRUE) 
logic
## TRUE FALSE  TRUE

typeof(logic)
## "logical"

typeof(F) # R会默认把T和F当作TRUE和FALSE的简写
## "logical"
3.1.5 复数类型和原始类型

分析数据基本用不到这两种类型,此处就不介绍了~

3.2 属性

属性是附加给原子型向量的额外信息,可以将属性赋予任意一个R对象

attributes(die) #因为die没有任何属性所以返回NULL,意思就是空值
## NULL

一个原子型向量最常见的三种属性是:名称(name)、维度(dim)和类(class)

3.2.1 名称属性

利用names()函数给die赋予名称属性,这个字符向量的长度要与die等长

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 # 我们可以发现显示die向量时,名称属性出现在了对应元素上方
##   one   two three  four  five   six 
##    1     2     3     4     5     6 

die + 1 # 但名称并不会对向量中的实际值产生影响,比如向量+1,名称不会变的。
##   one   two three  four  five   six 
##    2     3     4     5     6     7 

# 可以使用names()函数对名称属性批量修改或删除
names(die) <- c("uno", "dos", "tres", "quatro", "cinco", "seis") 
die
##    uno    dos   tres quatro  cinco   seis 
##      1      2      3      4      5      6 

# 删除名称属性值,只需将NULL赋予names函数
names(die) <- NULL
die
## 1 2 3 4 5 6
3.2.2 维度属性

原理同上,使用dim()函数即可

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) # 上面结果可见R默认按列进行数据填充,这个参数byrow = TRUE代表按行填充
m
##      [,1] [,2] [,3]
## [1,]    1    2    3
## [2,]    4    5    6

3.4 数组

array函数生成一个n维数组

args(array) # 查看array函数的参数,发现只有3个
## function (data = NA, dim = length(data), dimnames = NULL) 

# 利用arry创建一个三维数组
ar = array(c(11:14, 21:24, 31:34),dim = c(2,2,3));ar #2行2列3个切面
## , , 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

练习题:生成扑克牌矩阵

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 类

更改对象的维度并不会改变其类型,但会改变这个对象的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"

运行attributes函数时,对象的class属性并非总是会显示,可以使用class函数专门搜索对象的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 日期与时间

除了双整型、整型、字符型、逻辑型、复数类型和原始类型外,R的属性系统还能表示更多的数据类型。下面我们来了解下

now <- Sys.time() #该函数的目的是返回当前计算机的时间
now
## "2021-04-16 21:55:42 CST"

typeof(now)
## "double"
class(now)
##  "POSIXct" "POSIXt" 

没错,返回的感觉是一个字符串,但它的类型是双整型,它的类是POSIXct和POSIXt。POSIXct是一个广泛用于表示日期与时间的框架。在POSIXct框架下,使劲按被表示为自1970年1月1日零点(UTC时间)开始逝去的秒数。比如刚刚我电脑的时间相对这个时间已经过去了1618581342秒,因此在POSIXct下被存储为数值1618581342,所以typeof()返回的是双整型。

R用单个元素1618581342的双整型向量生成了一个时间对象,为了看到这个向量的本来面目,我们可以把事件对象now的class属性移除。

unclass(now)
## 1618581342

这就很有趣,给一个双整型向量,然后R会将一个包含两个类(POSIXct和POSIXt)的class属性赋给该双整型向量,此属性提醒R,正在处理POSIXct时间,应以特殊方式处理,即返回给我们可以理解的字符串形式

second <- 1234567
second
## 1234567

class(second) <- c("POSIXct", "POSIXt")
second
## "1970-01-15 14:56:07 CST"

至此我们知道R中其实很有特殊的类(class)。如果需要详细了解某个类时查看其帮助文档即可

3.5.2 因子

因子在R中用来存储分类信息,我们可以把因子视为性别类似的概念;它只可以去某些特定的值(男性或女性),而这些值之间可能有一些特殊的顺序规定(比如女士优先)。该特性非常适合记录分类变量如肿瘤、非肿瘤。

gender <- factor(c('male','female','female','male'))
typeof(gender) #R会将向量中的值重新编码为一串整数值并存储在一个整型向量中
## "integer"

attributes(gender)
## $levels
## [1] "female" "male"  

## $class
## [1] "factor"

unclass(gender) # unclass函数,可以看R到底如何存储因子的
## [1] 2 1 1 2
## attr(,"levels")
## [1] "female" "male" 

gender #R显示因子因子时用了levels属性,即1显示为female,2显示为male
## [1] male   female female male  
## Levels: female male

上述结果可见,向factor函数赋值一个向量可生成因子。R会将向量中的值重新编码为一串整数值并存储在一个整型向量中。此外R还会将一个levels属性和一个class属性添加到该整型向量中,levels属性包含显示因子值的一组标签,而class属性包含:factor。

因子的存在,使统计模型中加入分类变量很简单,因为这些分类变量已经被编码成一些数值

as.character(gender) #强制将因子转换为字符串
##  "male"   "female" "female" "male" 

3.6 强制转换

向量、矩阵、数值均只能存储单一类型数据:字符串型>数值型>逻辑型

a <- c(1,“TRUE”)
a
## “1” “TRUE”

b <- c(1,TRUE) #逻辑型中默认TRUE=1, FALSE=0
b
## 1  1

sum(c(TRUE,TRUE,FALSE,FALSE)) #会变成sum(c(1,1,0,0)),就是计算包含几个TRUE值
## 2
mean(c(TRUE,TRUE,FALSE,FALSE)) #mean函数计算TRUE值所占比例
## 0.5

类型之间强制转换需要用到as系列函数

as.character(1)
## "1"
as.logical(1)
## TRUE
as.numeric(FALSE)
## 0

3.7 列表

一维集合,列表将某些具体的值组织起来,而是组织R对象

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

[[]]代表来自列表中的第几个元素,[]代表来着这个元素的哪一个子元素。

练习:创建点数为1的红桃A

card <- list('ace', 'hearts', 1)
card
## [[1]]
## [1] "ace"

## [[2]]
## [1] "hearts"

## [[3]]
## [1] 1

3.8 数据框

数据库是列表的二维版本,重点:数据框以列为单位组织数据。不同列可以包含不同的数据类型。但数据框中的每一列都必须具有相同的长度

1.jpg
df <- data.frame(face = c("ace", "two", "six"),
                 suit = c("clubs", "clubs", "clubs"), 
                 value = c(1, 2, 3))# 需确保每个向量长度相等,face,suit,value均为对象的names属性
df
##   face  suit value
##   ace clubs     1
##   two clubs     2
##   six clubs     3

此时我们查看df的类型会发现是一个列表,class属性为数据框,实际上,每个数据框都有一个具有data.frame类的列表。可以用str函数查看这个列表或者数据框中,哪些对象被组织到一起了

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

重点!!!我们发现R将字符串存储成了因子(因为不做特殊处理R就会自动这样做)。加上这行命令即可实现字符串形式存储

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

至此我们可以利用数据框来生成一副扑克牌

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
##         等等

但每次想生成扑克牌都输入这么多的数据,非常繁琐且易出错,所以我们可以把这个数据存储为文件,用的时候读取即可。

3.9 保存和读取数据

write.csv(deck,file = 'deck.csv', row.names = F) #保存deck数据框,文件命名为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 总结

R中最常用的数据结构为向量、矩阵、数组、列表和数据框。注意区分他们的异同。

2.jpg
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 205,386评论 6 479
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,939评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,851评论 0 341
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,953评论 1 278
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,971评论 5 369
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,784评论 1 283
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,126评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,765评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,148评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,744评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,858评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,479评论 4 322
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,080评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,053评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,278评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,245评论 2 352
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,590评论 2 343

推荐阅读更多精彩内容

  • 夜莺2517阅读 127,711评论 1 9
  • 我是黑夜里大雨纷飞的人啊 1 “又到一年六月,有人笑有人哭,有人欢乐有人忧愁,有人惊喜有人失落,有的觉得收获满满有...
    陌忘宇阅读 8,520评论 28 53
  • 兔子虽然是枚小硕 但学校的硕士四人寝不够 就被分到了博士楼里 两人一间 在学校的最西边 靠山 兔子的室友身体不好 ...
    待业的兔子阅读 2,584评论 2 9
  • 信任包括信任自己和信任他人 很多时候,很多事情,失败、遗憾、错过,源于不自信,不信任他人 觉得自己做不成,别人做不...
    吴氵晃阅读 6,181评论 4 8