存储模式与基本类型
R的变量可以存储多种不同的数据类型,
可以用typeof()函数来返回一个变量或表达式的类型。比如
typeof(1:3)
## [1] "integer"
typeof(c(1,2,3))
## [1] "double"
typeof(c(1, 2.1, 3))
## [1] "double"
typeof(c(TRUE, NA, FALSE))
## [1] "logical"
typeof('Abc')
## [1] "character"
typeof(factor(c('F', 'M', 'M', 'F')))
## [1] "integer"
注意因子的结果是integer而不是因子。
R还有两个函数mode()和storage.mode()起到与typeof()类似的作用,
这是为了提供与S语言兼容所遗留的,
应停止使用。
R中数据的最基本的类型包括logical,
integer, double, character, complex, raw,
其它数据类型都是由基本类型组合或转变得到的。
character类型就是字符串类型,
raw类型是直接使用其二进制内容的类型。
为了判断某个向量x保存的基本类型,
可以用is.xxx()类函数,
如is.integer(x),is.double(x),is.numeric(x),is.logical(x),is.character(x),is.complex(x),is.raw(x)。
其中is.numeric(x)对integer和double内容都返回真值。
在R语言中数值一般看作double,
如果需要明确表明某些数值是整数,
可以在数值后面附加字母L,如
is.integer(c(1, -3))
## [1] FALSE
is.integer(c(1L, -3L))
## [1] TRUE
整数型的缺失值是NA,
而double型的特殊值除了NA外,
还包括Inf, -Inf和NaN,
其中NaN也算是缺失值, Inf和-Inf不算是缺失值。
如:
c(-1, 0, 1)/0
## [1] -Inf NaN Inf
is.na(c(-1, 0, 1)/0)
## [1] FALSE TRUE FALSE
对double类型,可以用is.finite()判断是否有限值,NA、Inf, -Inf和NaN都不是有限值;
用is.infinite()判断是否Inf或-Inf;is.na()判断是否NA或NaN;is.nan()判断是否NaN。
严格说来,NA表示逻辑型缺失值,
但是当作其它类型缺失值时一般能自动识别。NA_integer_是整数型缺失值,NA_real_是double型缺失值,NA_character_是字符型缺失值。
在R的向量类型中,
integer类型、double类型、logical类型、character类型、还有complex类型和raw类型称为原子类型(atomic types),
原子类型的向量中元素都是同一基本类型的。
比如,
double型向量的元素都是double或者缺失值。
除了原子类型的向量,
在R语言的定义中,
向量还包括后面要讲到的列表(list),
列表的元素不需要属于相同的基本类型,
而且列表的元素可以不是单一基本类型元素。
用typeof()函数可以返回向量的类型,
列表返回结果为"list":
typeof(list("a", 1L, 1.5))
## [1] "list"
原子类型的各个元素除了基本类型相同,
还不包含任何嵌套结构,如:
c(1, c(2,3, c(4,5)))
## [1] 1 2 3 4 5
R有一个特殊的NULL类型,
这个类型只有唯一的一个NULL值,
表示不存在。NULL长度为0,
不能有任何属性值。
用is.null()函数判断某个变量是否取NULL。
NULL值可以用来表示类型未知的零长度向量,
如c()没有自变量时返回值就是NULL;
也经常用作函数缺省值,
在函数内用is.null()判断其缺省后再用一定的计算逻辑得到真正的缺省情况下的数值。
要把NULL与NA区分开来,NA是有类型的(integer、double、logical、character等),NA表示存在但是未知。
数据库管理系统中的NULL值相当于R中的NA值。
类型转换与类型升档
可以用as.xxx()类的函数在不同类型之间进行强制转换。
如
as.numeric(c(FALSE, TRUE))
## [1] 0 1
as.character(sqrt(1:4))
## [1] "1" "1.4142135623731" "1.73205080756888" "2"
类型转换也可能是隐含的,比如,
四则运算中数值会被统一转换为double类型,
逻辑运算中运算元素会被统一转换为logical类型。
逻辑值转换成数值时,TRUE转换成1,FALSE转换成0。
在用c()函数合并若干元素时,
如果元素基本类型不同,
将统一转换成最复杂的一个,复杂程度从简单到复杂依次为:logical<integer<double<character。
这种做法称为类型升档,如
c(FALSE, 1L, 2.5, "3.6")
## [1] "FALSE" "1" "2.5" "3.6"
不同类型参与要求类型相同的运算时,
也会统一转换为最复杂的类型,
也称为类型升档,
如:
TRUE + 10
## [1] 11
paste("abc", 1)
## [1] "abc 1"
属性
除了NULL以外,
R的变量都可以看成是对象,
都可以有属性。
在R语言中,
属性是把变量看成对象后,
除了其存储内容(如元素)之外的其它附加信息,
如维数、类属等。
R对象一般都有length和mode两个属性。
常用属性有names, dim,class等。
attributes函数
对象x的所有属性可以用attributes()读取,
如
x <- table(c(1,2,1,3,2,1)); print(x)
##
## 1 2 3
## 3 2 1
attributes(x)
## $dim
## [1] 3
##
## $dimnames
## $dimnames[[1]]
## [1] "1" "2" "3"
##
##
## $class
## [1] "table"
table()函数用了输出其自变量中每个不同值的出现次数,称为频数。
从上例可以看出,table()函数的结果有三个属性,前两个是dim和dimnames,
这是数组(array)具有的属性;
另一个是class属性,值为"table"。
因为x是数组,可以访问如
x[1]
## 1
## 3
x["3"]
## 3
## 1
也可以用attributes()函数修改属性,
如
attributes(x) <- NULL
x
## [1] 3 2 1
如上修改后x不再是数组,也不是table。
attr函数
可以用attr(x, "属性名")的格式读取或定义x的属性。
如:
x <- c(1,3,5)
attr(x, "theta") <- c(0, 1)
print(x)
## [1] 1 3 5
## attr(,"theta")
## [1] 0 1
可以让向量x额外地保存一个theta属性,
这样的属性常常成为“元数据”(meta data),
比如,
用来保存数据的说明、模拟数据的真实模型参数,等等。
names属性
有元素名的向量、列表、数据框等都有names属性,
许多R函数的输出本质上也是列表,
所以也有names属性。
用names(x)的格式读取或设定。
如:
x <- 1:5
y <- x^2
lmr <- lm(y ~ x)
print(names(lmr))
## [1] "coefficients" "residuals" "effects" "rank"
## [5] "fitted.values" "assign" "qr" "df.residual"
## [9] "xlevels" "call" "terms" "model"
对于没有元素名的向量x,names(x)的返回值是NULL。
dim属性
dim属性的存在表明对象是矩阵或一维、多维数组。
如:
x <- matrix(1:12, nrow=3, ncol=4)
attr(x, "dim") # 等同于dim(x)
## [1] 3 4
修改dim属性就将向量转换成矩阵(数组),
或修改了矩阵的性质,
元素按列次序重排填入新的矩阵。如:
x <- 1:4
dim(x) <- c(2,2)
x
## [,1] [,2]
## [1,] 1 3
## [2,] 2 4
R允许dim仅有一个元素,
这对应于一维向量,
与普通的没有dim属性的向量有区别。
另外要注意,
取矩阵子集时如果结果仅有一列或一行,
除非用了drop=FALSE选项,
结果不再有dim属性,
退化成了普通向量。
类属
R具有一定的面向对象语言特征,
其数据类型有一个class属性,
函数class()可以返回变量类型的类属,
比如
typeof(factor(c('F', 'M', 'M', 'F')))
## [1] "integer"
mode(factor(c('F', 'M', 'M', 'F')))
## [1] "numeric"
storage.mode(factor(c('F', 'M', 'M', 'F')))
## [1] "integer"
class(factor(c('F', 'M', 'M', 'F')))
## [1] "factor"
class(as.numeric(factor(c('F', 'M', 'M', 'F'))))
## [1] "numeric"
class属性是特殊的。
如果一个对象具有class属性,
某些所谓“通用函数(generic functions)”会针对这样的对象进行专门的操作,
比如,print()函数在显示向量和回归结果时采用完全不同的格式。
这在其它程序设计语言中称为“重载”(overloading)。
class属性用来支持R的S3风格的类,
常用的有factor, 日期,日期时间,
数据框,tibble。
R还有S4、R6等风格的类。
str()函数
用print()函数可以显示对象内容。
如果内容很多,
显示行数可能也很多。
用str()函数可以显示对象的类型和主要结构及典型内容。例如
s <- 101:200
attr(s,'author') <- '李小明'
attr(s,'date') <- '2016-09-12'
str(s)
## int [1:100] 101 102 103 104 105 106 107 108 109 110 ...
## - attr(*, "author")= chr "李小明"
## - attr(*, "date")= chr "2016-09-12"
韭菜热线原创版权所有,发布者:风生水起,转载请注明出处:https://www.9crx.com/77942.html


