个人简介
·作者简介:大家好,我是小白,专注与医学相关的数据科学、机器学习和·人工智能。
·个人主页:仰望星空的小白🦅
·支持我:点赞 + 收藏 + 留言
·系列专栏:
·座右铭:宝剑锋从磨砺出,梅花香自苦寒来
目录
#提一个点 ,如果要换行就用shift + enter, 不要让RStudio给你乱加 + 号换号,+的含义与普通换行不同,有时候如果是不同句子的话就不要用+, 直接换行就好了。有时候问题就出在这里。
一、知识准备
第三章 R对象
typeof( )
3.1原子型向量
原子型向量就是最简单的包含数据的向量。
is.vector()测试某个对象是否为原子型向量。
每个原子型向量都将其值存储在一个一维向量中,并且只能是一种类型的数据。R可以识别六种基本类型:double、integer、character、logical、complex、raw(双整型、整型、字符型、逻辑型、复数类型、原始类型)
#R规范:输入整数后键入L表示输入一个整型数值。输入一个字符,相应字符加上双引号。
双整型:默认存储方式。
整型:计算机内存中,integer的定义方式要比double更加精确
#sqrt(2)^2 - 2 产生浮点误差
#原始类型向量用来存储数据的原始字节。
raw(3)
## 00 00 00
3.2属性
属性是附加给原子型向量的额外信息。把属性理解为对象的元数据metadata。它的作用是将这个对象相关的信息以一种便捷的形式存起来并附加给对象。某些函数会检查对象是否附有某些特定的属性值。这些函数会根据该数据对象的特等属性决定是否进行某些特定的操作。
用attribute函数可以查看一个对象包含哪些属性信息。如果一个对象没有任何属性信息,attributes会返回结果NULL,即空值。
一个原子型向量最常见的三种属性是:名称name,维度dim,类class。每个属性都有自己的辅助函数。用对应的函数可以查询对应属性名。
如图:有names函数加过名后就是Named num,否则是num
注意!names( ),names(x) <- c("X", "Y", "Z") #这里是names,不是name,s不能丢
对于有名称属性的向量,显示向量时,名称属性值会显示在对应元素的上方。
维度属性:原子型向量可以转换成一个n维数组,方法是用dim函数将相应的维度属性赋给该向量。
x <- c(1,2,3,4,5,6)
dim(x) <- c(2,3)
输出两行三列。
在分配维度属性时,R始终将第一个值赋给行数,将第二个值赋给列数。R将元素重新排列到不同的行和列时,是以列为优先顺序的,而不是行,会先把列填满。
args(matrix)
function (data = NA, nrow = 1, ncol = 1, byrow = FALSE, dimnames = NULL)
args(array)
function (data = NA, dim = length(data), dimnames = NULL)
array(1:3, c(2,4)) # recycle 1:3 "2 2/3 times"
# [,1] [,2] [,3] [,4]
#[1,] 1 3 2 1
#[2,] 2 1 3 2
## Example of setting row and column names
mdat <- matrix(c(1,2,3, 11,12,13), nrow = 2, ncol = 3, byrow = TRUE,
dimnames = list(c("row1", "row2"),
c("C.1", "C.2", "C.3")))
mdat
以上都是R里的帮助里的实例,一个是array的,一个是matrix的,需要了解的友友可以直接看这里面,我觉得还挺明白的。
3.3矩阵
3.2介绍了
3.4数组
3.2介绍了
3.5类
更改对象的dim并不会改变其类型,但会改变这个对象的class属性。从numeric变matrix。
double的class是numeric。
now <- Sys.time()
typeof(now)
## "double"
class(now)
## "POSIXct" "POSIXt"
#日期和时间:类型typeof是双整型、类class是POSIXct和POSIXt
unclass()变成numeric!
因子factor,存储分类信息。
## Map from 4 different values to only two levels:
(xf <- factor(x, levels = c("Male", "Man" , "Lady", "Female"),
labels = c("Male", "Male", "Female", "Female")))
#> [1] Male Male Male Female Female
#> Levels: Male Female
3.6强制转换coercion
3.7列表
list1 <- list(100:130, "R", list(TRUE, FALSE))
3.8数据框
数据框是列表的二维版本。
data.frame(……, stringsAsFactors = FALSE)
3.9加载数据
CSV文件(Comma-Separated Values)文件。Import Dataset → From text file(右上)
Import Dataset → From Web URL 加载互联网上的纯文本文件
head 检视数据集的前六行数据,tail检视后六行。给一个args设置实际行数。
3.10保存数据
write.csv(deck, file = "name.csv", row.names = FALSE)
getwd()
session > set working directory > choose directory
3.11小结
第四章 R的记号体系
4.1值的选取
deck[ , ] 第一个选行,第二个选列。
正整数、负整数、零、空格、逻辑值、名称六种创建索引的方式。
df[2, c(2, 3)] 选择第二行,第二、三列,共两个对象。
R的索引从1开始
如果只提取一列,R会返回一个向量,如果还想要数据框,加参数drop = FALSE。
负整数索引:R返回的元素将不包含负整数索引所对应的元素。
空格索引告诉R提取该索引位置所代表维度的所有元素。
如果在索引时提供一个包含TRUE和FALSE逻辑值的向量,那么R会匹配索引值为TRUE的行位置(或者列,这取决于索引向量放置的位置)并提取出相应的元素,而忽略所有索引值为FAlSE的行位置。
如果给过names()名称属性,可以用名称索引。
4.2发牌
把选择一行的操作放到一个函数就ok
4.3洗牌
先用sample(1:52,size = 52)洗牌,然后按照这个随机顺序选择出所有列。不过每一次都是取牌堆顶的一张牌,然后再放回去重新洗。
4.4美元符号与双中括号
这是第二种记号体系。要想提取数据框的某一列,使用$分隔数据框的名称与想要提取的列的名称。注意,列名不需要加双引号。R会将该列的所有值作为一个变量返回。这样的返回向量可以直接拿去算平均数、中位数,非常有用。
提取list里的element,也可以用$,这样提取出的是向量形式。如果用[]形式,R会返回新的列表对象。使用$时,R会原封不动地提取元素。如果list中element没有名称(或者不想使用名称),可以使用双中括号代替单括号,这样的记号方式与$的效果等同。这在知道想要选择的位置时很好用。
⬆️图是书里的
!!!杜绝使用attach。attach会导致R某些函数与其创建的计算环境发生冲突。attach针对某个对象单独重新创建一个计算环境。可以不用$索引。但将attach应用于某个数据集后,R可能会混淆两个变量的名称。
第五章 对象改值
这一讲挺重要,但是内容少,比较简单
tip:先制作一份原始数据的副本,在副本的数据上进行修改操作,可以确保在任何时候都有一份原始的数作为参考。
5.1就地改值
更改的时候先用索引选出自己要的改的部分,再加<-就行。
可以创建原先对象中并不存在的新值。R会自动将对象的长度延伸以适应新值。这也提供了一种为数据集添加新变量的方法。
data$new <- 1:52
data$new <- NULL 删除变量
5.2逻辑值取子集
R的7种逻辑运算符。>, >=, <, <=, ==, !=, %in%
最后一个 a %in% c(a,b,c) 后者是否包含前者?
注意
deck4$value[deck4$suit == "hearts"] <- 1
和
deck4[deck$face == "queen", ]的区别
布尔运算符可以将多个逻辑测试的结果整合并输出为一个TRUE或者FALSE
R有六种布尔运算符。
上面都是书里的图
5.3缺失信息
NA not available,用于存储缺失信息。计算中包括了NA,结果也是NA,但是如果添加参数na.rm = TRUE,R会在函数求值时忽略NA
NA==NA,通常意义上的逻辑测试并不能帮助你定位缺失值的位置。
is.na()用来测试某个值是否是一个缺失值。
5.4小结
通过结合R的记号体语法和赋值符<-,你可以在一个R对象的内部就地改值。这样便可以更新数据并清理数据集。
第六章 R的环境系统
6.1环境
R中的每一个对象都存储在一个环境当中。environment是一个类似于列表的对象,概念上接近于计算机上的文件夹,其实是树。每一个env都与一个父环境相连接,后者是高一层级的环境。这样的父子环境就构成了一个分层的环境系统。树形结构易于搜索R对象,但是这是单向的,可以知道父环境是什么,但不知道一个环境的子环境。
!可以通过devtools包中的parenvs函数查看R
parenvs(all = TRUE),现在parenvs函数在pryr包中。
6.2操作R环境
as.environment函数接受一个环境名称(字符串)作为输入,并返回改名称所对应的环境。
环境树中有三个环境拥有自己的调用函数。他们是:全局环境(R_GlobalEnv)、基环境(base)、空环境(R_EmptyEnv)
globalenv()
baseenv()
emptyenv()
可以用parent.env函数查看某一个环境的父环境。空环境是R中唯一没有父环境的环境。空环境是空的,基环境里有很多R对象。打开R会话后创建的所有对象都会存储在全局环境中。
assign函数将对象存储到某个特定环境当中。assign 的用法是,首先提供新的对象的名称(用字符串形式作为输入),然后提供新对象的取值,最后在提供想要存储的环境名称。
assign("new", "Hello Global", envir = globalenv())
这样可以准确的在某个环境中赋值和覆盖。其实和<-的意义一样。
在任何时候,R的活动环境都只有一个。所以新对象都会被存储在该环境中,并且在搜索对象时,R会优先搜索该环境。active environment。
environment( )查看当前活动环境。
6.3作用域规则scoping rules
搜索对象的规则称为scoping rules
1.首先在当前环境active envir 搜索
2.在command line中工作时,active envir 就是global envir
3.当所要搜索的对象不在当前的活动环境中时,R会进入该环境的父环境,然后进入该父环境的父环境,直到达到环境树的顶层环境(emptyenv),搜索停止。
函数也是一种R对象,存储和搜索的方式和其他对象无区别。
6.4赋值
重复赋值 = 覆盖
规避覆盖风险:R在每一次运行函数时,都会创建一个新的活动环境,函数的运行是在新环境中进行的。
6.5函数求值
R will create a new environment during evaluation. We call it runtime environment. R 会将一个函数的运行时环境与第一次创建该函数时所在的环境相连接。可以通过environmnet()查看一个函数的原环境。
R的函数求值:当调用一个函数之前,R是在活动环境中工作的。我们可以将此活动称为调用环境。调用函数时R创建原环境的子环境,作为当前活动环境。接着R运行代码,此时创建的任何对象会被存储在活动环境中。R调用对象时通过scoping rules搜索。最后,当R完成函数运行时,它会将活动环境切换为调用环境。然后R会执行代码中调用该函数的所有命令。
6.6闭包
以上代码和图都是书里的。
可以看出,deck被安全保存在运行时环境里,父环境里的数据没有改变。list函数是闭包(受保护)的关键。通过list,函数内的对象可以通过选择列表对象的方式被选择,我们把从list中选择出的函数副本保存为新函数,这样会让我们在运行函数时,新函数的父环境不是全局环境,而是list所在函数的环境。