一、就地改值
利用标号体系直接将新值赋予指定位置,适用于知道修改目标确切位置时。
- 如果你赋予一个不存在的位置值时,R会自动将对象长度延伸,使之得以匹配。
- 这种直接标号增加新行或列的方式还可以作用在数据框中,当然数据框还可以通过名称
frame$+属性
的形式,赋值。 - 而在对列表进行类似操作时,需要注意,列表形成之后补充的元素也必须是列表形式,只有一开始列表刚形成时,可以有各种其他数据类型。
> test<-c(1,2,3)
> test[4]<-4
> test
[1] 1 2 3 4
> test[6]<-6 #跨位置赋值,匹配NA
> test
[1] 1 2 3 4 NA 6
> list<-list(c(1,2,3),c("one","two","three"))
> list[3]<-list(c(1,2,3))
> list
[[1]]
[1] 1 2 3
[[2]]
[1] "one" "two" "three"
[[3]]
[1] 1 2 3
而这种情况出现在矩阵上时会报错
matrix[,6]=c(2,2,3,3)
Error in `[<-`(`*tmp*`, , 6, value = c(2, 2, 3, 3)) :
subscript out of bounds
之前R语言的环境系统介绍过,常规赋值是无法在函数体内部对函数外的对象进行直接赋值的,那么如果你确实想这么做怎么办呢?可以使用<<-的特殊赋值符号,这和在with(,{})中对外对象赋值是一个道理
> a<-2
> test<-function(){
+ a<<-3
+ }
> test()
> a
[1] 3
二、逻辑值取值
逻辑值取值是R语言的一大亮点,是基于数据类型强制转化而来的,需要重点掌握
测试数据,一下是6张卡片,包含字母、颜色和数字三个属性:
A 红 3
B 红 2
C 红 1
A 黑 3
B 黑 2
C 黄 1
1.单条件
假设需要找到所有所有A卡片,并将数字改为4
首先需要说明,针对上述情况完全可以采用就地改值的方式实现。但是很多时候我们只有判断条件,而卡片位置不清楚,或者卡片太多不适宜一一罗列,此时逻辑取子集的作用就很明显了。
首先介绍一下R的其中逻辑运算符:
R会根据比较结果返回一个逻辑值:TRUE或者FALSE,当运算符作用在向量间,则会每个元素一一比较:
> c(1,2,3)==c(1,2,4)
[1] TRUE TRUE FALSE
> 1>c(0,0,0)
[1] TRUE TRUE TRUE
只有%in%是判断是否存在,因此不会进行一一对比
> c(1,2)%in%c(3,1,2,4)
[1] TRUE TRUE
此时,我们考虑获得卡片A所在的位置
> cards$C1=="A"
[1] TRUE FALSE FALSE TRUE FALSE FALSE
通过数据类型强行转化的知识我们知到,将该向量作为取值索引,可以TRUE对应的行选出来,之后利用就地改值实现目标,即
> cards$C3[cards$C1=="A"]<-4
> cards
C1 C2 C3
1 A 红 4
2 B 红 2
3 C 红 1
4 A 黑 4
5 B 黑 2
6 C 黑 1
2.多条件
我们继续考虑这么一个问题,如果我们要利用类似的方法将黑色A卡片的点数换成5又该怎么办呢?
①当然我们可以先选出为A的卡片所在的位置,并在这基础上找到为“黑”色A卡,并将其数字换位5,具体代码如下:
cards[cards$C1=="A",]$C3[cards[cards$C1=="A",]$C2=="黑"]<-5
类似地
cards$C3[cards[cards$C1=="A",]$C2=="黑"]<-6
> cards
C1 C2 C3
1 A 红 4
2 B 红 6
3 C 红 1
4 A 黑 6
5 B 黑 2
6 C 黑 6
得到的是错误的结果,因为半部分表示定位代码得到的最终结果是FALSE,TRUE,而左边对应全集确有6行。根据对应原则,将不断重复T,F六次,直至与向量长度一致,因此有3行的数字都变为了6
显然这种写法很容易出错,且随着条件的增多代码越发的复杂,为了更好地解决这种多条件赋值问题,我们引入布尔运算符
②布尔运算符可以将多个逻辑测试的结果整合并输出为一个TRUE或FALSE,R共有六种布尔运算符,具体如下:
此时回过头来想问题,我们只需将卡片字母为“A”和颜色为“黑”条件用&连在一起,在利用就地取值即可达到目标。(存在双运算符&&和||,相对于单运算符来说,如果第一个条件的测试结果已经很明显了,则不会进行第二组测试,这可以提高代码运行效率双运算符。但需要注意的是,双运算符并不是向量化的运算符,两侧只能是单个逻辑测试)
> cardpos<-cards$C1=="A"&cards$C2=="黑"
> cards$C3[cardpos]<-6
> cards
C1 C2 C3
1 A 红 3
2 B 红 2
3 C 红 1
4 A 黑 6
5 B 黑 2
6 C 黑 1
3.逻辑值转位置
有时候直接使用逻辑值结果赋值并不方便,如利用c[-x,]去取不在某个位置的数据,此时需要使用which(+逻辑判断语句),将逻辑结果转化为具体的位置。当然如果你十分喜欢逻辑值,可以使用!将TRUE和FALSE发生对调然后再进行匹配。
三、缺省值
缺省值是数据处理最为常见的问题,在R中我们依旧采用NA(not available)来表示缺失的信息。
1. na.rm
在对含NA的数据进行计算时,得到的结果往往也是NA,为了避免这种情况,一般的函数都会有na.rm(NA remove)参数,用以移除NA值,如
> mean(c(NA,1:20),na.rm = TRUE)
[1] 10.5
2. is.na
因为NA的不确定性,导致无法通过一般的逻辑测试确定位置信息
> NA==NA
[1] NA
而is.na函数就可以达到这个目的
> test<-c(NA,1,2,NA)
> is.na(test)
[1] TRUE FALSE FALSE TRUE