Advertisement

R语言-对象改值

阅读量:

一、就地改值
利用标号体系直接将新值赋予指定位置,适用于知道修改目标确切位置时。

  • 如果你赋予一个不存在的位置值时,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逻辑运算符
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
    
      
      
      
    

全部评论 (0)

还没有任何评论哟~