标签:
最基本的类型是存储单一数值的类型. 主要包括 Numeric, Integer, Complex, Character, Logical 等.
Numeric 或者 “double” 是 R 优先选择的存储数值的方式, 相当于 C 中的 “double”. 需要注意的是, 有的时候认为 Numeric 是 “integer” 和 “double” 的统称. .Machine$double.double.eps
等变量给出环境中的存储 double 的限度.
Integer 是整数, 相当于 C 中的 “int”. 一般不管有没有小数点的数字, R 默认存成 Numeric, 这个时候需要使用 as.integer 函数强制去把数存为 Integer. .Machine$integer.max
给出能够存储的最大的整数, 总是 2^31 - 1 = 2147483647 .
Complex 是复数的存储形式.
Character 是存储字符和字符串的类型. 字符串和字符都可以存储.
Logical 是存储 bool 值的类型, 只有 TRUE (T) 和 FALSE (F) 两个值.
Date 类型是专门为存储时间设计的. POSIXct 把时间保存为一个整数, 为某时间距离 1970 年 1 月 1 日的时间. POSIXlt 则保存一个列表, 其中有年月日时分秒的信息. 使用 unclass 可以把相应的类转换为基本类. 相应函数有 as.POSIXct, as. POSIXlt, strptime, strftime, ISOdate, ISOdatetime 等, 还有 chron 包可以处理时间.
数据往往不是单一的值, R 有很好的存储多值数据的结构.
vector, 向量, 类似一维的 array, 存储相同的基本类型, 如果有字符型的元素, 则所有的值都会转为字符型. 需要注意的是, 长度为 1 的也可以是 vector, 所以使用 is.vector 函数进行判断也会显示 TRUE
, 也就是说所有单一的基本元素变量都会被认为是一个 vector. 而对于不同长度的 vector, 使用 class 或者 mode 等函数去判断其类型的话, 都会给出其基本元素的类型, 如果一个 vector 中所有元素都是 character 则返回 character.
这样的方式给人的策略是 R 语言试图忽视单复数的差别. 其实把单一数据和向量的类型不做太多区分正是 R 语言的特点的反应. R 语言用于处理大量数据, 那么其构造和逻辑就更符合这样的需求. 例如, 如果对一个实际上长度不为 1 的整数向量加 1, 得到的是和原向量的每个值加 1 的新的向量.
x <- 1:6
x + 1
[1] 2 3 4 5 6 7
如果是两个等长向量相加, 则是对应的元素一个个相加.
x <- 1:6
y <- 1:6
x + y
[1] 2 4 6 8 10 12
如果两个向量长度不等长, 那么只有一个长度是另一个长度的倍数才能相加. 而短的向量则会重复为长度和长向量一样长. 其实这样看也就理解了当短向量长度为 1 的时候的结果其实是个特例. 这也是 R 语言淡化单一值和向量之间区别的一个特点.
x <- 1:6
z <- 1:2
x + z
[1] 2 4 4 6 6 8
Factor 是一种能够帮助节省内存空间的方式. 如果一系列的值中有较多重复的值, 可以使用 factor, factor 中只会存储一份原值, 而原来的值本身会存为数字, 这样就会节省空间.
原值被称为水平 (level), 可以自己去设置顺序等. levels 函数可以返回一个 factor 所有可能的 level, 而 nlevels 则可以返回 level 的个数.
把一个向量转换成 factor 只要使用 as.factor 函数. 有的时候需要我们把数字先转换成 factor, 经过一定处理之后需要再把 factor 转换称为数字, 这个时候不能直接使用 as.numeric, 因为 as.numeric 会直接返回 factor 内部的值, 而不是原来的值. 我们需要先使用 as.character 或者 levels 先得到字符, 然后再转换为数字.
myfactor <- factor(c(10, 20, 20, 50, 20, 10), levels=c(10,20,50), ordered=TRUE)
as.numeric(levels(myfactor)[myfactor])
as.numeric(as.character(myfactor))
有的时候我们会需要去生成某种类型的 factor 来做参数或者测试数据, 那么可以使用 gl 函数. gl 函数可以记成 “generate levels” 的缩写. gl 函数的参数主要有: n
用来设置 level 的个数; k
用来设置每个 level 重复的次数; length
来设置长度, 其实有了前两个参数这个可以忽略; labels
用来设置 level 的值; ordered
接受 bool 值, 设置是否 level 是排列好顺序的.
需要注意的是, 在使用 c 函数把若干个因子组合在一起的时候, 需要先把因子转换为原来的值再使用 c 函数, 否则 c 函数直接把因子当作存在内存中的数字而丢失原来的意思.
如果我有一个向量, 其中是连续的值, 我现在想要画直方图, 我可以直接用相应的函数画出来. 如果我不需要看到图, 而只想要知道这些值都怎么分布在区间内, 我就可以使用 cut 函数. cut 函数把数值分成不同的区间, 然后把原来的向量转化为 level 为区间的因子, 这样就能知道某个值属于哪个区间. 原向量和因子的长度相等, 因子的 level 是自己设定的. 使用 table 函数就可以统计每个区间中数值的个数.
aaa <- c(1,2,3,4,5,2,3,4,5,6,7)
cut(aaa, 3)
[1] (0.994,3] (0.994,3] (0.994,3] (3,5] (3,5] (0.994,3] (0.994,3]
[8] (3,5] (3,5] (5,7.01] (5,7.01]
Levels: (0.994,3] (3,5] (5,7.01]
cut(aaa, 3, dig.lab = 4, ordered = TRUE)
[1] (0.994,3] (0.994,3] (0.994,3] (3,5] (3,5] (0.994,3] (0.994,3]
[8] (3,5] (3,5] (5,7.006] (5,7.006]
Levels: (0.994,3] < (3,5] < (5,7.006]
有的时候, 我需要去了解两个因子之间有多少组合, 这时候就可以选择 interaction 函数, interaction 函数可以给出多个因子 level 的组合. 这些组合并不都有数据, 如果设置 drop = TRUE
则会扔掉没有数据的 level, 而只保留真的有数据的 level.
a <- gl(2, 4, 8)
b <- gl(2, 2, 8, labels = c("ctrl", "treat"))
interaction(a, b, drop = TRUE, sep = ".")
[1] 1.ctrl 1.ctrl 1.treat 1.treat 2.ctrl 2.ctrl 2.treat 2.treat
Levels: 1.ctrl 2.ctrl 1.treat 2.treat
matrix, 二维的 array, 所有的元素都是相同类型. as.matrix, is.matrix.
在取 matrix 中的元素的时候, 可以使用下标来操作. 一般情况下, 下标按照 [ROW, COL] 来取, 其中 ROW 和 COL 都可以是向量, 可以是指示想要取出的行号或者列号的向量, 也可以是 bool 值的向量. 如果方括号中没有逗号, 而按照 [NUM] 来取矩阵中的元素, 则会返回把矩阵当作一维的向量排列后对应位置的值, 如果是 2 乘 2 矩阵, [3] 则会返回 [2,1] 的值, 原矩阵会按照列优先延展成向量.
在取矩阵的一个行或者列后, 其返回值的维度会减少, 在取下标的时候, 使用参数 [,, drop = FALSE]
则不会让矩阵所取结果的值的维度减少.
矩阵在内存中是按照行优先或者列优先存储的一维的向量, 所以如果需要建立一个矩阵, 最好是先建立一个足够大的矩阵, 然后向其中填数, 而不应该去建立一个小的矩阵, 然后使用 rbind 或着 cbind 去补充. 因为如果矩阵的数量增加, R 需要重新申请空间, 并且, 如果添加的行或者列和存储的优先不一样的话, 则需要重新对矩阵元素进行排序, 这样的话就会使得效率十分低下. 所以, 建立矩阵应该建立足够大的矩阵, 如果最后不需要这么大的矩阵, 只要重新赋值一次就好.
array, 可以有很多维.
list, 列表, 可以把不同类型的变量组合在一起, list 中也可以包含子 list.
取列表中的元素就需要特别注意, 如果使用单方括号 “[]”, 所取出的结果就是该列表的一个子列表, 而如果想要获得其本身内容, 则需要使用双方括号 “[[]]” 或者美元符号 “$”. 取元素可以使用名称, 也可以使用数字.
mylist <- list(one = "one", two = c(2, 2))
mylist
$one
[1] "one"
$two
[1] 2 2
mylist["one"]
$one
[1] "one"
mylist[["one"]]
[1] "one"
mylist$one
[1] "one"
由于列表中可以放各种类型的对象, 这就为把多种多样相关的数据整合在一起提供了便利. 一个 list 可以不准确地看作是 C++ 语言中专门用来存储数据的 class. 一些相关变量, 为了和其他的变量区分, 往往会取相似的变量名, 当变量十分多的时候, 这样的方法依然不方便查询. 我们就可以把这些相关的变量都放在一个列表中, 然后通过取下标的方法访问变量. 如果忘记了变量名, 还可以通过 names 函数或者 str 函数去查询包含在列表中的变量名. 这样的方法十分适合保存对多个数据集进行相同或相似的处理结果, 可以使用 for 循环来完成数据的保存.
rna.gene.fpkm <- list() # 需要提前建立空的列表.
for (nam in dir(rna.cuffnorm.result.dir)) {
rna.gene.fpkm[[nam]] <- read.table( # 建立列表元素并赋值
file.path("./",
nam,
"genes.fpkm_table"),
header = TRUE,
sep = "\t")
}
列表在内存中的保存并不是连续的, 而是像 C 语言中的链表一样的分散开的, 所以对列表增加元素并不像矩阵那样效率低, 对于列表或者相应的数据框, 使用 rbind 则不会像对矩阵使用那么缓慢. 这也是为什么, 我们可以先建立一个空列表 (或数据框), 然后通过 for loop 等方式逐渐向其中高效地添加元素.
data.frame, 数据框, 是一种特别的 list, 其像 matrix 一样限制了每列的变量长度必须要一样, 但同时也像 list 一样, 每一列的变量类型可以不同. 数据框实际上看着非常像我们常用的 Excel 中的一个表, 数据框的列名和行名也分别对应于 Excel 表格中的列名和行名. 由于数据框具有 list 和 matrix 的特点, 所以对数据框进行取元素也有 list 和 matrix 取元素的特点, 我们既可以像 list 一样使用 “$” 取一个列, 也可以像 matrix 一样使用 “[ROW, COL]” 取其中一个特定的值.
常用的查询变量类型的函数有: mode, storage.mode, class 和 typeof. 这些函数有一些差别.
如果需要知道环境中每个基本类型能存储的大小, 可以查询 .Machine
这个 list, 相应的大小存储在该 list 中.
由于种种原因, 数据中可能会出现缺失值的情况, R 会用 NA 来替代相应的空值. 如果是计算后产生的空值, 则会用 Inf 或者 NaN 来代替. 处理空值是数据分析中的必要部分.
标签:
原文地址:http://blog.csdn.net/ngs_learning/article/details/51200592