参考资料:学习R
1、类
R中所有变量都有一个类,表明此变量属于什么类型。例如,大部分的数字是numeric类,逻辑值是logical类。其实,因为R没有标量类型(scalar type),所以更严格地我说,数字向量应该是numeric类,逻辑向量是logical类。
我们可以使用class(my_variable)来找出变量的类名,如下:
所有变量除了类之外,还有一个内部存储类型、一个模式、一个存储模式,但在实际中我们需要使用对象的类即可。
2、不同类型的数字
R中包含三种不同类型的数值变量:浮点值numeric、整数integer和复数complex。我们可以检查变量的类型class把它们分辨出来:
class(sqrt(1:10))
# i用于创建复数的虚部
class(3+1i)
# 尽管只有一个数字,也是一个numeric类
class(1)
# 冒号操作符返回的值是numeric类
class(0.5:4.5)
# 当所有值是整数时返回整数类型
class(1:5)
3、其他通用类
除了我们已知的数字类和逻辑值,向量还有其他三个类,它们分别是:用于存储文本的字符character,存储类别数据的因子factor,以及比较少见的存储二进制数据的原始值raw。
R语言不区分整个字符串和单个字符——只包含一个字符的字符串与其他字符串的处理相同。
在许多编程语言中,类别数据用整数表示。例如,gender 中用 1 来代表 female,2 代表male。 稍好的办法是把 gender 当作带有“female” 和“male” 选项的字符变量。 然而,因为类别数据与传统的纯文本是不同的概念, 所以从语义上看这仍然不妥。 R 找到了一种更有效的方法, 把这两种方法整合到一个语义正确的类里面——因子(factor), 即拥有标签的整数:
因子的内容看起来与它们所对应的字符一样——这样每个值都能得到一个可读性很好的标签。这些标签被限制在称为因子水平(levels of the factor)的特定值中(本例中为“female”和“male”)
gender<-factor(c("male","female","female","male","female"))
gender
levels(gender)
nlevels(gender)
as.integer(gender)
请注意,即使“male”是gender中的第一个值,第一个水平仍然是“female”。默认情况下,因子水平按字符顺序分配。
在底层,因子的值被存储为整数而非字符串,我们可以调用as.integer清楚的看到。采取整数而非字符文本的存储方式,令内存的使用非常高效,尤其当出现大量重复字符串时。如果我们再夸张一点,生成 10 000 个随机的 gender 值(使用 sample 函数对字符串“female” 和“male” 随机采样 10 000 次并使用 replace 选项),可以看到,一个因子包含的值比同等字符占用更少的内存。在以下代码中,sample 返回一个字符向量( 这是使用as.factor 转换而成的),而 object.size 则返回每个对象的内存分配大小。
gender_char<-sample(c("female","male"),10000,replace=TRUE)
gender_fac<-as.factor(gender_char)
object.size(gender_char)
object.size(gender_fac)
当操作因子水平的内容时(常见的例子是:清理命名,例如,把所有男性字符统一为“male”,而非“Male”),最好先把因子转换成字符串后再处理,以便充分利用字符串操作函数。可以使用as.character函数完成转换:
4、检查和更改类
直接在命令提示符下,以交互的方式键入类class的函数名来检查变量是很有用的。但是如果现在脚本中测试对象的类型,则最好用is函数,或针对某个类写的特定函数。通常我们会做这样测试:
大部分的类都会有自己的is.*函数。通常,直接调用它们比使用通用is函数稍显高效。
例如:
我们可以使用以下命令来查看所有的is函数:
在这个命令中,ls列出所有的变量名,"^is"是一个正则表达式,它意味着“匹配所有以is开头的字符串”,而baseenv函数则返回base包中所有的环境。
有时候,我们想改变一个对象的类型,这就是所谓的转型(casting),大部分的is函数都有与之对应的as函数。尽可能使用特定的as.*函数而不使用as函数,因为它们通常更有效,而且往往针对该类会有额外的逻辑。
5、检查变量
挡在控制台输入一个运算或变量时,结果就会被打印出来,因为R隐式调用了对象的print函数。所以再命令提示符下输入1+1与print(1+1)是一样的。
对于内循环函数来说,自动打印功能不起作用,我们必须显式地调用print:
除了查看变量的打印输出,最好我们可以看到某种程度的对象汇总信息。summary函数就能为不同的数据类型提供汇总信息。例如,数值变量会被汇总统计出平均数、中位数,以及一些分位数。在下例中,runif函数生成30个平均分布于0和1之间的随机数:
类别变量和逻辑变量将根据每个值得计算进行汇总。在下例中,letters是一个内置的常数,它包含了从a到z的小写值(大写的LETTERS则包含了类似的从A到Z的大写值)。这里letters[1:5]用索引限制letters的范围为从a到e。sample函数使用重复抽样随机抽取30次。
fac<-as.factor(sample(letters[1:5],30,replace=TRUE))
summary(fac)bool<-sample(c(TRUE,FALSE,NA),30,replace=TRUE)
summary(bool)
多维对象与矩阵及数据框一样,都是通过列来汇总的。下面创建一个数据框:
dfr<-data.frame(num,fac,bool)
# 查看前几行
head(dfr)
# 胡数据框的summary函数就行是对每列调用summary一样
summary(dfr)
类似地,str函数能显示对象的结构。str函数对数据框和嵌套列表非常有用。
如前所述,每个类都有自己的打印(print)方法,以控制如何显示到控制台。有时,这种打印模糊了其内部结构,或忽略了一些有用的信息。用unclass函数可以绕开这一点,显示变量时如何构建的。例如,对因子调用unclass函数会显示它仅是一个整数向量,拥有一个叫levels的属性。
attributes函数能显示当前对象的所有属性列表:
6、工作区
工作时,我们往往想知道已经创建的变量及其内容。用ls函数即可列出现有变量的名称。默认情况下,变量名以.开头的是隐藏文件。要查看它们,可传入all.names=TRUE参数。
工作一段时间后,尤其是在数据挖掘中,工作区会变得相当凌乱,我们可以使用rm函数删除变量来清理区间:
rm(list=ls())要慎用。会删除所有变量