44. R编程(六:向量类型详解1)

2021-12-17 09:09:08 浏览数 (3)

基础

广义来说,向量有三种类型:

  • 存储相同数据类型的atomic vector;
  • 不同类型的 list。
  • NULL,长度为零的vector。

属性(attributes):

  • 纬度,二维的矩阵,多维的array;
  • 类型 class,专门用于S3 类对象的构造。

image.png

向量分类

常见的有四种:

  • 特别的书写规范:

image.png

  • 处理NA 值的注意事项:

image.png

除此之外,还有两种不常见的:参见:https://www.cnblogs.com/mfrank/p/14051513.html

属性

一共有三种获得的函数:

代码语言:javascript复制
a <- 1:3
attr(a, "x") <- "abcdef"
attr(a, "x")
#> [1] "abcdef"

attr(a, "y") <- 4:6
str(attributes(a))
#> List of 2
#>  $ x: chr "abcdef"
#>  $ y: int [1:3] 4 5 6

# Or equivalently
a <- structure(
  1:3, 
  x = "abcdef",
  y = 4:6
)
str(attributes(a))
#> List of 2
#>  $ x: chr "abcdef"
#>  $ y: int [1:3] 4 5 6

attributes 可以批量获取对象所有的属性;structure 可以批量定义对象所有的属性。

此外属性一般也是短暂形成的:

只有names, 和dim 属性会被继承(说继承可能不太严谨,但你大概明白我的意思吧~):

代码语言:javascript复制
> b <- matrix(1:4, ncol=2)
> b
     [,1] [,2]
[1,]    1    3
[2,]    2    4
> attributes(b)
$dim
[1] 2 2

> names(b) <- 3
> b
     [,1] [,2]
[1,]    1    3
[2,]    2    4
attr(,"names")
[1] "3" NA  NA  NA 
> b[q]
Error in b[q] : invalid subscript type 'closure'
> b[1]
3 
1 
> b[2]
<NA> 
   2 
> attributes(b[2])
$names
[1] NA
  • 创建带名字的向量的三种方式:

如果名称中有确实值的话:

  • 获取向量、矩阵、array 信息的函数异同:

image.png

S3 类向量

一个对象,一旦有了class 属性,则其会变为S3 类型对象:

代码语言:javascript复制
> x1
[1] 3
> 
> otype(x1)
[1] "base"
> attr(x1, "class") <- "good"
> otype(x1)
[1] "S3"
> attributes(x1)
$class
[1] "good"

其实我们通常使用的因子类型,也是S3 对象,此外还有:

因子

  • 因子是基于整型向量改写的S3 对象,而许多的因子实际上由字符串转换而来的:
代码语言:javascript复制
> x3
[1] a b
Levels: a b
> mode(x3)
[1] "numeric"

> x4 <- gsub("a", "aa", x3)
> x4
[1] "aa" "b" 
> mode(x4)
[1] "character"

这也是为什么我们如果用c() 连接因子,会得到数字:

因为实际使用的是factor 背后的integer 值。

代码语言:javascript复制
> x3
[1] a b
Levels: a b
> x2
[1] 1 2 3
Levels: 1 2 3
> c(x2,x3)
[1] 1 2 3 1 2

因此,如果需要转换因子,最好的方法是显式修改;如果需要避免factor 转型,则等向量一切处理完毕后,在转换为因子。

另外,在处理因子的时候还需要谨慎levels 属性。我们在将向量转为因子时,可以使用默认顺序下的levels 或手动设定,此时向量本身顺序并不会改变;但如果对已创建的因子转换levels,则因子本身顺序也会按照levels 的顺序改变。

因子取子集,去除其他不包含levels的方法:

其他

  • 日期

image.png

  • 日期-时间

image.png

  • 时间段

反映的是两段时间的差值:

列表

从大类上,list 是区别于atomic 的另一大类向量。

最大的区别在于,list 可以存储不同类型的数据。

list 也可以有自己的多维矩阵:

从输出结果来看,它与atomic 创建的矩阵无二,但本质来说,其是不同的。atomic 的矩阵如果将元素修改与整体类型不同,则会强迫转型。

数据框

  • 识别非法名称

image.png

  • tibble

可以使用运算符号创建

  • 为什么要窄长的ggplot 类型数据,不要长宽数据

转换rownames 的方法:

  • 数据框中定义列表的方法
  • 数据框中定义矩阵与数据框的方法

个人感觉如果存放复杂的或多个纬度的数据,使用tibble会好一点:

代码语言:javascript复制
> dfm <- data.frame(
    x = 1:3 * 10
  )
> dfm$y <- matrix(1:9, nrow = 3)
> dfm$z <- data.frame(a = 3:1, b = letters[1:3], stringsAsFactors = FALSE)
> dfm <- data.frame(
    x = 1:3 * 10
  )
> dfm$y <- matrix(1:9, nrow = 3)
> dfm$z <- data.frame(a = 3:1, b = letters[1:3], stringsAsFactors = FALSE)
> dfm
   x y.1 y.2 y.3 z.a z.b
1 10   1   4   7   3   a
2 20   2   5   8   2   b
3 30   3   6   9   1   c
> dfm$y.1
NULL

# 这里y 矩阵的三个维度会被强制命名后缀增加.1,.2,.3 

> tibble::as_tibble(dfm)
# A tibble: 3 x 3
      x y[,1]  [,2]  [,3]   z$a $b   
  <dbl> <int> <int> <int> <int> <chr>
1    10     1     4     7     3 a    
2    20     2     5     8     2 b    
3    30     3     6     9     1 c   

data.frame 太容易让人confusing !

0 人点赞