R 入门笔记

PS:初学R  为了查阅方便 借鉴的网友的博客和自己的总结记录一下 

http://blog.csdn.net/jack237/article/details/8210598

命令简介

  R对大小写是敏感的;名称不能以数字开始;
    基本的命令由表达式或者赋值语句组成。如果一个表达式被作为一条命令给出,它将被求值、打印而表达式的值并不被保存。一个赋值语句同样对表达式求值之后把表达式的值传给一个变量,不过并不会自动的被打印出来;
    命令由分号(;)来分隔,或者另起新行;
    基本命令可以由花括号(f和g)合并为一组复合表达式;
    注释几乎可以被放在任何地方,只要是以井号( # )开始,到行末结束;
    如果一个命令在行莫仍没有结束,R将会给出一个不同的提示符,默认的是‘+’。

基本数据结构

 基本数据对象 

向量(vector), 见下节
矩阵(matrix): 
更一般的说数组是向量在多维情况下的一般形式。事实上它们是可以被两个或更多的指标索引的向量,并且以特定的方式被打印出来。
因子(factors) 提供了一种处理分类数据的更简介的方式。
列表(list):  
是向量的一种一般形式,并不需要保证其中的元素都是相同的类型,而且其中的元素经常是向量和列表本身。
数据框(data frame)
是一种与矩阵相似的结构,其中的列可以是不同的数据类型。可以把数据框看作一种数据"矩阵",它的每行是一个观测单位,而且(可能)同时包含数值型和分类的变量。
函数( function)
能够在R的workspace中存储的对象。我们可以通过函数来扩展R的功能。

 

向量与赋值

R对命名了的数据结构进行操作。最简单的数据结构是数字向量;如,
> x <- c(10.4, 5.6, 3.1, 6.4, 21.7)    c()是创建函数,赋值运算符是'<-',与函数assign()等价
> assign("x", c(10.4, 5.6, 3.1, 6.4, 21.7))  也可以写成:
> c(10.4, 5.6, 3.1, 6.4, 21.7) -> x
如果一个表达式被当作一个完整的命令,它的值将被打印到终端但不被储存。
单独输入x则会将值打印出来。也可以打印倒数:
> 1/x
> y <- c(x, 0, x)   也可以将向量作为元素。

 

 向量运算

    操作是按照向量中的元素一个一个进行的。同一个表达式中的向量并不需要具有相同的长度。如果它们的长度不同,表达式的结果是一个与表达式中最长向量有相同长度的向量。表达式中较短的向量会根据它的长度被重复使用若干次(不一定是整数次),直到与长度最长的向量相匹配。而常数很明显的将被不断重复。如,
> v <- 2*x + y + 1


常用运算有:+,-,*,/,^(次方);

 

log, exp, sin, cos, tan,sqrt等;
max和min的作用是选出所给向量中最大的或最小的元素;
range函数的值是一个长度为2的向量,即c(min(x),max(x))
length(x)返回了向量x中元素的个数,也就是x的长度。
sum(x)给出了x中所有元素的总和;
prod(x)给出x中所有元素的乘积;
mean(x)和var(x),分别计算样本均值和样本方差,这两个函数分别相当于sum(x)/length(x),sum((x-mean(x)) \^2)/(length(x) -1)。如果var()的参数是一个n*p的矩阵,那么函数的值是一个p*p的样本协方差矩阵,认为每行是一个p变量的样本向量。
sort(x)返回一个与x具有相同长度的向量,其中的元素按招升序排列。还有其他更灵活的排序功能(参见order()sort.list())。
pmaxpmin将返回一个与最长的向量长度相等的向量,向量中的元素由参数中所有向量在相应位置的最大值(最小值)组成;
如果要使用复数,需要直接给出一个复数部分。因此sqrt(-17)将会返回NaN(无效数值)和一个警告,而sqrt(-17+0i)将按照复数进行运算。

 

生成序列

最简单的方法是用冒号‘:’,冒号具有最高运算优先级。例如1:30就是向量c(1,2,. . .,29,30)。30:1构造一个递减序列。
利用seq()函数构造序列:有五个参数,from, to, by, length, along
                                       from, to可以不写参数名,seq(2,10)就相当于2:10。
                                       by指定步长,默认为1,如seq(-5, 5, by=.2)即为c(-5.0, -4.8, -4.6, ..., 4.6, 4.8, 5.0)
                                       length指定序列长度,如seq(length=51, from=-5, by=.2),等同于seq(-5, 5, by=.2)
                                       along=vector只能单独使用,产生一个“1:length(vector)”序列。类似的函数是rep(),这个函数可以用多种复杂的方法来                          
                                           复制一个对象。最简单的形式是> s5 <- rep(x, times=5)

 

逻辑向量

TRUEFALSE, 和NA(not available), 前两个可以简写为T和F,但T/F并不是系统保留字,可以被用户覆盖,所以最好还是不要简写。
逻辑向量是由条件给出的,如下列语句令temp成为一个与x长度相同,相应位置根据是否与条件相符而由TRUE或FALSE组成的向量:
> temp <- x > 13
逻辑操作符包括<, <=, >, >=,完全相等==和不等于!=,与或非分别为&, |, !。
在普通运算中,FALSE当做0而TRUE当做1。

 

 缺失值

NA(not available): 一般来讲一个NA的任何操作都将返回NA。
     is.na(x)返回一个与x等长的逻辑向量,并且由相应位置的元素是否是NA来决定这个逻辑向量相应位置的元素是TRUE还是FALSE。
     x==NA是一个与x具有相同长度而其所有元素都是NA的向量。
NaN(Not a Number): 由数值运算产生,如0/0, Inf-Inf.
     is.na(x)对于NA和NaN值都返回TRUE,
     is.nan(x)只对NaN值返回TRUE。

 

字符向量

 

字符串在输入时可以使用单引号(')或双以号(");  在打印时用双引号(有时不用引号)。
R使用与C语言风格基本相同的转义符, 所以输入\\打印的也是\\, 输入\" 打印引号",  \n: 换行, \t: tab, \b: 回格。
字符向量可以通过函数c()连接
paste()可以接受任意个参数,并从它们中逐个取出字符并连成字符串,形成的字符串的个数与参数中最长字符串的长度相同。如果参数中包含数字的话,数字将被强制转化为字符串。在默认情况下,参数中的各字符串是被一个空格分隔的,不过通过参数sep=string 用户可以把它更改为其他字符串,包括空字符串。例如:
> labs <- paste(c("X","Y"), 1:10, sep="")  使变量labs成为字符变量c("X1", "Y2", "X3", "Y4", "X5", "Y6", "X7", "Y8", "X9", "Y10")

 

 

 index vector---数据集子集的选择与修改

 

任何结果为一个向量的表达式都可以通过追加索引向量(index vector)来选择其中的子集。
1 逻辑的向量
> y <- x[!is.na(x)]    表示将向量x中的非NA元素赋给y;
> (x+1)[(!is.na(x)) & x>0] -> z     表示创建一个对象z,其中的元素由向量x+1中与x中的非缺失值和正数对应的向量组成。
2. 正整数的向量
> x[6]    是x的第六个元素
> x[1:10]       选取了x的前10个元素(假设x的长度不小于10)。
> c("x","y")[rep(c(1,2,2,1), times=4)]     产生了一个字符向量,长度为16,由"x", "y", "y", "x"重复4次而组成。
3. 负整数的向量
> y <- x[-(1:5)]       表示向量y取向量x前5个元素以外的元素。
4. 字符串的向量
只存在于拥有names属性并由它来区分向量中元素的向量。这种情况下一个由名称组成的子向量起到了和正整数的索引向量相同的效果。
> fruit <- c(5, 10, 1, 20)
> names(fruit) <- c("orange", "banana", "apple", "peach")
> lunch <- fruit[c("apple","orange")]
子集的修改
> x[is.na(x)] <- 0    表示将向量x中所以NA元素用0来代替
> y[y < 0] <- -y[y < 0]      表示将向量(-y)中 与向量y的负元素对应位置的元素 赋值给 向量y中 与向量y负元素对应的元素。作用相当于:
> y <- abs(y)

 

 有序因子和无序因子

因子是一种向量对象,它给自己的组件指定了一个离散的分类(分组),它的组件由其他等长的向量组成。R提供了有序因子和无序因子。
通俗点说,因子就是将对象的值分成不同的组levels)。
用函数factor()创建一个因子,levels按序排列(字母序或数值序)。

例如province<-c("四川","湖南","江苏","四川","四川","四川","湖南","江苏","湖南","江苏"),为province创建因子:
> pf<-factor(province)   创建province的因子pf
> pf     打印出来
 [1] 四川 湖南 江苏 四川 四川 四川 湖南 江苏 湖南 江苏
Levels: 湖南 江苏 四川
函数levels()可以用来观察因子中有多少不同的levels。

假如我们拥有这些省份考生的分数:
> score<-c(95,86,84,92,84,79,86,99,85,90)
函数tappley()可以用来计算各省的平均分数,函数tapply()的作用是对它第一个参数的组件中所包含的每个组应用一个参数三指定的函数。
> smeans<-tapply(score,pf,mean)
> smeans
    湖南     江苏     四川 
85.66667 91.00000 87.50000 
再例如,下面命令会给出各组的length
> tapply(score,pf,length)
湖南 江苏 四川 
   3    3    4 

函数ordered()可以创建有序因子
> ordered(province)
 [1] 四川 湖南 江苏 四川 四川 四川 湖南 江苏 湖南 江苏
Levels: 湖南 < 江苏 < 四川

 

数组和矩阵

数组

数组可以看成一个由递增下标表示的数据项的集合,例如数值。
数组的生成
如果一个向量需要在R中以数组的方式被处理,则必须含有一个维数向量作为它的dim属性。
维度向量由dim()指定,例如,z是一个由1500个元素组成的向量。下面的赋值语句
> dim(z) <- c(3,5,100)        使它具有dim属性,并且将被当作一个3X5X100的数组进行处理。 c(3,5,100) 就是他的维度向量。
还可以用到像matrix()array()这样的函数来赋值。比如
> array(1:20, dim=c(4,5))
> matrix(1:24, 3,4)
数据向量中的值被赋给数组中的值时,将遵循与FORTRAN相同的原则"主列顺序",即第一个下标变化的最快,最后的下标变化最慢。


数组的运算
数组可以在算数表达式中使用,结果也是一个数组,这个数组由数据向量逐个元素的运算后组成,通常参与运算的对象应当具有相同的dim属性。

数组的索引和数组的子块

数组中的单个元素可以通过下标来指定,下标由逗号分隔,写在括号内。
我们可以通过在下标的位置给出一个索引向量来指定一个数组的子块,不过如果在任何一个索引位置上给出空的索引向量,则相当于选取了这个下标的全部范围。
如a[2,,],a[,3,]等

索引数组

除了索引向量,还可以使用索引数组来指定数组的某些元素。
例如:有4X5的数组a,若要得到a中的a[1,3], a[2,2] 和a[3,1]这三个元素,可以生成索引向量i,然后用a[i]得到它们。
> a <- array(1:20,dim=c(4,5)) # Generate a 4 by 5 array.
> i <- array(c(1:3,3:1),dim=c(3,2))
> i
[,1] [,2]
[1,] 1 3
[2,] 2 2
[3,] 3 1
> a[i]
[1] 9 6 3
> a[i] <- 0   # 将这三个元素用0替换。

数组的索引和数组的子块

数组中的单个元素可以通过下标来指定,下标由逗号分隔,写在括号内。
我们可以通过在下标的位置给出一个索引向量来指定一个数组的子块,不过如果在任何一个索引位置上给出空的索引向量,则相当于选取了这个下标的全部范围。
如a[2,,],a[,3,]等

 

引数组

除了索引向量,还可以使用索引数组来指定数组的某些元素。
例如:有4X5的数组a,若要得到a中的a[1,3], a[2,2] 和a[3,1]这三个元素,可以生成索引向量i,然后用a[i]得到它们。
> a <- array(1:20,dim=c(4,5)) # Generate a 4 by 5 array.
> i <- array(c(1:3,3:1),dim=c(3,2))
> i
[,1] [,2]
[1,] 1 3
[2,] 2 2
[3,] 3 1
> a[i]
[1] 9 6 3
> a[i] <- 0   # 将这三个元素用0替换。

 

向量,数组的混合运算

表达式从左到右被扫描;
参与运算的任意对象如果大小不足,都将被重复使用直到与其他参与运算的对象等长;
当较短的向量和数组在运算中相遇时,所有的数组必须具有相同的dim属性,否则返回一个错误;
如果有任意参与运算的向量比参与运算的矩阵或数组长,将会产生错误;
如果数组结构正常声称,并且没有错误或者强制转换被应用于向量上,那么得到的结果与参与运算的数组具有相同的dim属性。

 

矩阵的运算

构建分区矩阵:cbind()和rbind(),cbind()按照水平方向,或者说按列的方式将矩阵连接到一起。rbind()按照垂直的方向,或者说按行的方式将矩阵连接到一起。

 

外积:操作符是%o%:
> ab <- a %o% b   或者
> ab <- outer(a, b, "*")
其中的乘法操作可以由任意一个双变量的函数替代。

广义转置:函数t(A),或aperm(A, c(2,1));

获取行数/列数nrow(A)和ncol(A)分别返回矩阵A的行数和列数。

矩阵乘法:操作符为%*%;

交叉乘积(cross product):crossprod(X,Y)等同于t(X) %*% y,crossprod(X)等价于crossprod(X, X);

diag(v):如果v是向量,diag(v)返回一个由v的元素为对角元素的对角矩阵。
               如果v为矩阵,diag(v)返回一个由v主对角元素组成的向量。
               如果v只是一个数值,那么diag(v)是一个vXv的单位矩阵。

 

特征值和特征向量eigen(Sm)。这个函数的结果是由名为values和vectors的两部分组成的列表。如果只是需要特征值:eigen(Sm)$values

最小二乘拟合即QR分解:lsfit(), qr()。

强制转换为向量:as.vector(),或者直接c().

线性方程和求矩阵的逆,奇异值分解行列式见<R语言笔记>;

 

列表和数据帧

列表

列表是由称作组件的有序对象集合构成的对象。组件的模式或类型不一定相同。
形如Lst <- list(name_1=object_1, . . ., name_m=object_m)的赋值将创建一个包含m个组件的列表,并根据参数中指定的名称为其命名。(其名称可以自由选取)。如果它们的名称被省略,组件将只是被编号。例如:
> Lst <- list(name="Fred", wife="Mary", no.children=3,child.ages=c(4,7,9))

所使用的组件是被复制到新的列表中的,对原始对象没有影响。
组件总是被编号的,并且可以通过编号指定。
Lst[[1]] 即为"Fred",也可以用 Lst$nameLst[["name"]]指定。如果Lst[[4]]是一个有下标的数组,Lst[[4]][1]就是它的第一项。
区分Lst[[1]]和Lst[1],'[[...]]'是选择单个元素时使用的操作符,而'[...]'是一个一般的下标操作符。因此,前者代表列表Lst中的第一个对象;后者是列表Lst的子列表,仅包含列表的第一项。
组件的名称可以缩写,可缩写的程度是只要能令组件被唯一的识别就可以了。如:Lst$na等价于Lst$name, Lst$w等价于Lst$wife。

扩展列表
可以通过指定额外组件的方式例如
> Lst[5] <- list(matrix=Mat)

 

连接列表
当连接函数c()的参数为列表时,其结果也是一个模式为列表的对象。由参数中的列表作为组件依次连接而成。
> list.ABC <- c(list.A, list.B, list.C)

 

数据帧

 

数据帧是类别为"data.frame"的列表;
数据帧会被当作各列具有不同模式和属性的矩阵。
数据帧按照矩阵的方式显示,选取的行或列也按照矩阵的方式来索引。

创建数据帧

直接创建:那些满足对数据帧的列(组件)限制的对象可以通过函数data.frame来构建成为一个数据帧
> t <- data.frame(home=statef, loot=income, shot=incomef)
强制转换:如果一个列表的组件与数据帧的限制一致,这个列表就可以通过函数as.data.frame()强制转化为一个数据帧。
外部文件:创建数据帧最简单的方法应当是使用read.table()函数从外部文件中读取整个数据帧。

数据帧和列表的限制

1 组件必须是向量(数值型,字符形,逻辑型),因子,数值矩阵,列表,或其他数据帧;
2 矩阵,列表,数据帧向新数据帧提供的变量数分别等于它们的列数,元素数和变量数;
3 数值向量,逻辑值和因子在数据帧中保持不变,字符向量将被强制转化为因子,其水平是字符向量中所出现的值;
4 数据帧中作为变量的向量结构必须具有相同的长度,而矩阵结构应当具有相同的行大小。

 

挂接和卸载数据帧

当觉得使用'$'引用数据帧元素(如't$home')麻烦时,可以进行数据帧挂接
attach(t)      这样可以直接引用数据帧内的元素,而无需'$',前提是数据帧外没有同名的变量(如name)。
挂接后若要对数据帧元素进行赋值操作,仍需用'$',否则视为赋值给数据帧外的元素。
赋值后必须要先卸载(detach)再重新挂接后,新值才可见。
detach(t)

 

attach()是具有一般性的函数,即它不仅能够将目录和数据帧挂接在搜索路径上,还能挂接其他类别的对象。特别是模式为"list"的对象可以通过相同的方式挂接:
> attach(any.old.list)     
任何被挂接的对象都可以用detach来卸载,通过指定位置编号或者指定名称这样的方式.

搜索路径
函数search()将显示目前的搜索路径,可以用来查看数据帧/列表的挂接状态。
ls()(或objects())命令可以用来检查搜索路径任意位置上的内容。如:ls(), ls(2), ls(t)
R可以在搜索路径中包含至多20个项目,列表和数据帧只能在位置2或更靠后的位置上挂接。

 

数据帧使用惯例

 

1 将每个独立的,适当定义的问题所包含的所有变量收入同一个数据帧中,并赋予合适的、易理解、易辨识的名称;
2 处理问题时,当相应的数据帧挂接于位置2,同时在第1层工作目录下存放操作的数值和临时变量;
3 在结束一次工作之前,将你认为对将来有参考价值的变量通过$标记的形式添加到数据帧里面,然后detach();
4 最后,将工作目录下所有不需要的变量剔除,并且尽量将剩下多余的临时变量都清除干净。
这样我们可以很简单的在同一个目录下处理多个问题,而且对每个问题都可以使用x,y,z这样的变量名。

 

语句组、循环和条件操作

R是一种表达式语言,也就是说其命令类型只有函数或表达式,并由它们返回一个结果。
语句组由花括号‘{ }’确定,此时结果是该组中最后一个能返回值的语句的结果。

条件语句

> if (expr_1) expr_2 else expr_3 
其中条件表达式expr1必须返回一个逻辑值,操作符&&和||经常被用于条件部分。
&和|与&&,||的区别在于,&和|按照逐个元素的方式进行计算,&&和||对向量的第一个元素进行运算,只有在必需的时候才对第二个参数求值。
if/else结构的向量版本是函数ifelse,其形式为ifelse (condition,a,b),产生函数结果的规则是:如果condition[i]为真,对应a[i]元素;反之对应的是b[i]元素。根据这个原则函数返回一个由a,b中相应元素组成的向量,向量长度与其最长的参数等长。

循环语句

for (name in expr_1) expr_2
其中name是循环变量,expr1是一个向量表达式(通常是1:20这样的序列),而expr2经常是一个表达式语句组,expr2随着name依次取expr1结果向量的值而被多次重复运行。

repeat(expr)

while(condition) expr

 

break语句可以用来中断任何循环,可能是非正常的中断。而且这是中止repeat循环的唯一方式。

next语句可以中止一个特定的循环,跳至下一个.

 

全局变量和局部变量

函数内的赋值都是局部变量,退出函数就丢失了。
如果要在函数内进行永久赋值(定义全局变量),需要用到“超赋值”操作符, <<-或者函数assign()。

posted @ 2017-03-24 23:24  George_sz  Views(468)  Comments(0Edit  收藏  举报