数据结构
向量
向量包含atomic vector和list,它们有三个共同性质属性:
- 类型 typeof()
- 长度 length()
- 属性 attributes(),附加的任意元数据
###
原子向量atomic vector包含:
- logical
- integer
- double 即 numeric
- character
- complex 复合型
- raw 原始型
其中后两者属于罕见类型
###
原子向量使用c()来创建,在c()中使用NA,NA会自动被转换成正确的数据类型,NA有以下几种类型:
- NA_real_
- NA_integer_
- NA_character_
###
is.numeric()通常用来判断向量的“数值性”,无论是整型还是双精度型向量都返回TRUE。所以如果需要精确的判断,还是要用is.integer或is.double
###
atomic vector中的每个元素都必须具有相同的类型,所以如果把不同的数据结合成一个向量,他们会被强制转换成最具有灵活性的数据类型。数据类型的灵活性排序为:character > double > integer > logical
###
不要使用is.vector()来判断一个对象是否是向量,只有在对象是向量且除了名字之外没有其他属性的情况下它才返回TRUE,前面定义了向量的概念,所以判断向量应该用 is.atomic() || is.list()
###
列表使用list()来创建,有时被称作递归(recursive)向量,因为一个列表可以包含其他列表
x <- list(list(list(list())))
str(x)
#List of 1
# $ :List of 1
#  ..$ :List of 1
#  .. ..$ : list()
###
c()可以将多个列表结合在一起,但如果把原子向量和列表放在一起,c()会强制把原子向量转换成列表
x <- list(list(1,2),c(3,4))
y <- c(list(1,2),c(3,4))
str(x)
#List of 2
# $ :List of 2
#  ..$ : num 1
#  ..$ : num 2
# $ : num [1:2] 3 4
str(y)
#List of 4
# $ : num 1
# $ : num 2
# $ : num 3
# $ : num 4
属性
###
attr()可以单独访问对象的一个属性,attributes()可以同时访问所有属性
y <- 1:10
attr(y,"my_attributes") <- "This is a vector"
structure(1:10,my_attributes = "This is a vector")
两种方式是相同效果的。
###
默认情况下向量被修改后它的大多数属性都会丢失,除了以下三个:
- name
- dimension
- class
这三个属性都使用各自专门的存取函数,而不能用attr()来做操作,可以使用uname()来删除向量的名称
###
因子factor是只能包含预先定义值的向量,因子建立在整型向量的基础上,只有两个属性class()和levels()
###
进行读取文件操作时,一个很好用的配置项stringsAsFactors = FALSE,避免了默认设置下字符串向量被转换成因子向量(挺烦人的)。
###
structure(1:5,comment = "my attribute")
#> [1] 1 2 3 4 5
没有显示属性的原因是comment属性是一个特殊的属性,它默认不输出,是隐式保存的,只能用attributes()或comment()来调取
###
f1 <- factor(letters)
levels(f1) <- rev(levels(f1))  # 整个f1对象被倒序了
f2 <- rev(factor(letters))  # 只有数值被倒序了,levels没有
f3 <- factor(letters,levels = rev(letters))  # 只有levels被倒序了
矩阵和数据框
###
使用plyr::rbind.fill(),如果合并数据框时两个数据框列数不同,则将没有的列以NA填充
###
数据框实际上是一个向量列表,所以数据框可能有某一列是list
df <- data.frame(x=1:3)
df$y <- list(1:2,1:3,1:4)
# 也可以写成
df <- data.frame(x=1:3,y=I(list(1:2,1:3,1:4)))
#> str(df)
#>'data.frame':	3 obs. of  2 variables:
#> $ x: int  1 2 3
#> $ y:List of 3
#>  ..$ : int  1 2
#>  ..$ : int  1 2 3
#>  ..$ : int  1 2 3 4
同理数据框的某一列也可以是matrix或array,只要生成时用I()包裹即可,但应该小心,很多函数默认数据框的每一列都是atomic vector
