学习R语言笔记:
参考书籍:《R语言入门教程》、《R语言初学者指南》
R数据类型:
1. R基本数据类型(或称为原子类型):
数值型(numberic) 1,2,3.33
复数型(complex) 1+2i
字符型(character) "hello world"
逻辑型(logical) FALSE/TRUE #注意为大写
> a <- 100
> mode(a) ##mode函数求数据模式
[1] "numeric"
> b <- 1+2i
> mode(b)
[1] "complex"
> d <- "hello word"
> mode(d)
[1] "character"
> c <- FALSE
> mode(c)
[1] "logical"
2.基本数据对象:向量(vector)、矩阵、因子、列表、数据框、函数
类型识别
对象类型可以通过is函数返回的布尔值来判断:
is.array()
is.matrix()
is.list()
is.data.frame()
is.factor()
is.ordered()
typeof()函数可以获得对象中元素的类型(如 logical, integer, double, complex, character, and list)。
类型转换
as.vector():将矩阵转换为矢量。
as.array()
as.matrix():将数据框转换为矩阵。
as.list()
as.data.frame():将矩阵转换为数据框。
matrix():将矢量组合为矩阵。
cbind()和rbind():将矢量组合为矩阵。
data.frame():将矩阵转换为数据框。
unlist():将列表转换为矢量。
which():将布尔矢量转换为索引矢量。
常用对象
可以用typeof()函数获得对象的类型(type)。
可以用mode()函数获得对象的模式(mode)。
可以用storage.mode()函数获得对象的存储模式(storage mode)。
可以用class()函数获得对象的所属的类。
数值与向量
2.1 向量与赋值
>x <- c(10.4, 5.6, 3.1, 6.4,21.7)
创建了一个名为x,包含5个数字的向量。
函数c的作用就是将参数中的数值向量以及向量的值首尾相接组成一个新的向量。
<- 为赋值操作符(还可以改变方向使用->)。assign函数同样可以进行赋值操作。
>assign("x",c(10.4, 5.6, 3.1, 6.4,21.7))
2.2 向量运算
向量可以被用于表达式中,操作时按照向量中的元素一个一个进行的。若表达式中的向量不是相同的长度时,
表达式中较短的向量会根据它们的长度被循环重复使用,直到长度匹配。
> x <- c(1:3)
> y <- c(4:9)
> x
[1] 1 2 3
> y
[1] 4 5 6 7 8 9
> v <- x + y #x长度不够,将循环从第一个位置开始
> v
[1] 5 7 9 8 10 12
>
逐个元素进行运算的操作符包括: +、-、*、/、^,此外所有普通运算函数都能够被使用(log、exp、sin、cos、tan、sqrt等)。
max和min 作用是选出所给向量中最大的或者最小的元素。
length 返回向量中元素的个数(即向量的长度)。
sum 向量中所有元素的总和
prod 向量中所有元素的乘积
mean 计算样本均值( sum(x)/length(x) )
var 计算样本方差( sum((x - mean(x))\^2)/(length(x)-1) ),若var的参数是一个n*p的矩阵,
则函数的值就是一个p*p的样本协方差矩阵,认为每行是一个p变量的样本向量。
sort 排序函数,其中的元素按照升序排列。
2.3 产生规则序列
seq 产生一个序列(可以指定起始、结束数据以及步长(或者长度),默认步长为1)
> t <- seq(1,3)
> t
[1] 1 2 3
> t <- seq(1,5)
> t
[1] 1 2 3 4 5
> t <- seq(1,5,2)
> t
[1] 1 3 5
> t <- seq(to = 5,from = 1,by = 3)
> t
[1] 1 4
> t <- seq(to = 5,from = 1,length = 1)
> t
[1] 1
> t <- seq(to = 5,from = 1,length = 2)
> t
[1] 1 5
>
> t <- seq(to = 5,from = 1,length = 3)
> t
[1] 1 3 5
rep 复制对象(重复的复制)
> t <- c(1,2,3)
> t
[1] 1 2 3
> t2 <- rep(t,2)
> t2
[1] 1 2 3 1 2 3
> > t <- c(1,2,3)
2.4 逻辑向量
逻辑向量的值可以是TRUE、FALSE和NA(not available).
逻辑操作包括<, <=, >, >=, == 和 != 。此外还有 &(逻辑与and,元素按位与)、|(逻辑或or,元素按位)、!(取反),
&&表达式与、||表达式或。
> t <- c(1,2,4,7,5,8)
> t
[1] 1 2 4 7 5 8
> judge <- t > 3
> judge
[1] FALSE FALSE TRUE TRUE TRUE TRUE
> !judge
[1] TRUE TRUE FALSE FALSE FALSE FALSE
> judge & (1 > 3)
[1] FALSE FALSE FALSE FALSE FALSE FALSE
> judge | (1 > 3)
[1] FALSE FALSE TRUE TRUE TRUE TRUE
> judge && (1 > 3)
[1] FALSE
2.5 缺失值(NA,NaN)
一般来讲,对一个NA的任何操作都将返回NA。
is.na(x) 返回一个逻辑变量,测试x是否为NA或者NaN
is.nan(x) 测试一个值是否为NaN
> z <- c(1:3,NA)
> z
[1] 1 2 3 NA
> isna <- is.na(z)
> isna
[1] FALSE FALSE FALSE TRUE
> isnan <- is.nan(z)
> isnan
[1] FALSE FALSE FALSE FALSE
>
2.6 字符向量
字符向量用引号(')或者双引号(“)。
paste 可以接受任意个参数,并从它们中逐个取出字符并连成字符串,形成的字符串的个数与参数中最长字符串的长度相同。
> labs <- paste(c("X","YZ"), 1:5, sep="[]")
> labs
[1] "X[]1" "YZ[]2" "X[]3" "YZ[]4" "X[]5"
>
2.7 索引向量(index vector),数据集子集的选择与修改
选择一个向量中的子集可以通过在其名称后追加一个方括号的索引向量来完成。
> x <- c('json','bson','xml')
> x
[1] "json" "bson" "xml"
> tmp <- x[1:2]
> tmp
[1] "json" "bson"
2.8 对象的其他类型
矩阵、因子、列表、数据框、函数
对象,模式和属性
3.1 固有属性:模式和长度
R所操作的实体是对象。R最基本的结构:数值型(numeric)、复值型(complex)、逻辑型(logical)以及字符型(character)。
向量中的值必须是相同模式的。
R操作对象还包括列表,它的模式是列表型(list)。列表是对象的有序序列,其中的元素可以是任意模式的。
通过模式,可以确定对象的基本类型。模式是对对象的一种特性。对象的另一种特性是它的长度。
函数mode和length利益返回对象的模式和长度。(更深入的属性可以通过attributes获得。)
> x <-c(12,12,12.4)
> mode(x)
[1] "numeric"
> length(x)
[1] 3
> x <-c(12,12,"12.4")
> mode(x)
[1] "character"
> length(x)
[1] 3
3.2 改变对象的长度
一个“空”对象具有的模式。例如:
> e <- numeric()
> e
numeric(0)
> mode(e)
[1] "numeric"
> length(e)
[1] 0
> e[3] <- 10
> e
[1] NA NA 10
>
3.3 对象的属性
函数attributes(object)将给出当前对象所具有的所有非基本属性(长度和模
式属于基本属性)的一个列表。函数attr(object,name)可以被用来选取一个
指定的属性。
3.4 对象的类别
对象的一个特别属性,类别,被用来指定对象在R编程中的风格。
有序因子与无序因子
因子是一种向量对象,它给自己的组件指定了一个离散的分类(分组),它的组件由其他等长的向量组成。因子分为有序和无序两种。??????????未理解
> colour <- c('G', 'G', 'R', 'Y', 'G', 'Y', 'Y', 'R', 'Y')
> col <- factor(colour)
> col
[1] G G R Y G Y Y R Y
Levels: G R Y
> col1 <- factor(colour, levels = c('G', 'R', 'Y'), labels = c('Green', 'Red', 'Yellow'))
> col1
[1] Green Green Red Yellow Green Yellow Yellow Red Yellow
Levels: Green Red Yellow
> col2 <- factor(colour, levels = c('G', 'R', 'Y'), labels = c('1', '2', '3'))
> col2
[1] 1 1 2 3 1 3 3 2 3
Levels: 1 2 3
> colour <- c('G', 'G', 'R', 'Y', 'G', 'Y', 'Y', 'R', 'Y')
> col <- factor(colour)
> values <- c(255,255,125,000,255,000,000,125,000)
> inmeans <- tapply(values,col,mean)
> inmeans
G R Y
255 125 0
tapply函数的作用是它的第一个参数的组件中所包含的的每个组应用一个函数。
4.3 有序因子
ordered 函数用来创建有序因子。
> score <- c('A', 'B', 'A', 'C', 'B')
> score1 <- ordered(score, levels = c('A', 'B', 'C'))
> score1
[1] A B A C B
Levels: A < B < C
数组和矩阵
5.1 数组
数组是一个有递增下标表示的数据项的集合。
一个矩阵就是一个2维数组。维数向量中的值规定了下标k的上限。下限一般为1。
如果需要在R中以数组的方式处理一个向量,则需要含有一个维数向量作为他的dim属性。
如:
> z <- c(1,2,3,4,5,6)
> dim(z) <- c(2,3) #c(2,3) 是z的维度向量
> z
[,1] [,2] [,3]
[1,] 1 3 5
[2,] 2 4 6
还可以用matrix()和array()这样的函数来赋值
> array(1:6,c(2,3)) #数组函数
[,1] [,2] [,3]
[1,] 1 3 5
[2,] 2 4 6
> matrix(1:6,2,3) #矩阵函数
[,1] [,2] [,3]
[1,] 1 3 5
[2,] 2 4 6
>
5.2 数组的索引和数组的子块
数组中的单个元素可以通过下标来索引。还可以通过下标索引向量来指定一个数组的子块。
> m <- matrix(1:6,2,3)
> m
[,1] [,2] [,3]
[1,] 1 3 5
[2,] 2 4 6
> m(1,)
[1] 1 3 5
> m[1,1]
[1] 1
>
5.3 索引数组
通过索引数组来指定数组中的某些元素。
> a <- array(1:20,dim=c(4,5))
> i <- array(c(1:3,3:1),dim=c(3,2))
> a
[,1] [,2] [,3] [,4] [,5]
[1,] 1 5 9 13 17
[2,] 2 6 10 14 18
[3,] 3 7 11 15 19
[4,] 4 8 12 16 20
> i
[,1] [,2]
[1,] 1 3
[2,] 2 2
[3,] 3 1
> a[i] #索引数组a中[1,3]、[2,2]、[3,1]位置上的数据
[1] 9 6 3
> a[i] <- 0
> a
[,1] [,2] [,3] [,4] [,5]
[1,] 1 5 0 13 17
[2,] 2 0 10 14 18
[3,] 0 7 11 15 19
[4,] 4 8 12 16 20
>
5.4 向量,数组的混合运算
1)表达式从左到右被扫描。
2)参与运算的任意对象如果大小不足,将会被重复使用直到与其他参与运算的对象等长。
3)当较短的向量和数组在运算中相遇时,所有的数组必须具有相同的dim属性,或者返回一个错误。?????
4)如果有参与运算的向量比参与运算的矩阵或数组长,将会产生错误。????????
5)如果数组结构正常声称,并且没有错误或者强制转换被用于向量上,那么得到的结果与运算的数组具有相同的dim属性。??????
5.5 两个数组的外积
外积操作符是%o%。
如果a,b是两个数组型数组,他们的外积是一个数组,其维数向量由二者的维数向量连接而成(与顺序有关),而其
数据向量由a的数据向量和b的数据向量中所有元素的所有可能乘积组成的。
>ab <- a %o% b
或者
>ab <- outer(a,b,"*")
> a <- array(c(1:4),dim=c(2,2))
> b <- array(c(5:8),dim=c(2,2))
> ab <- a %o% b
> ab
, , 1, 1 #b[1,1]数据乘以数组a
[,1] [,2]
[1,] 5 15
[2,] 10 20
, , 2, 1 #b[2,1]数据乘以数组a
[,1] [,2]
[1,] 6 18
[2,] 12 24
, , 1, 2 #b[1,2]数据乘以数组a
[,1] [,2]
[1,] 7 21
[2,] 14 28
, , 2, 2 #b[2,2]数据乘以数组a
[,1] [,2]
[1,] 8 24
[2,] 16 32
>
5.6 数组的广义转置
aperm(a, perm) 函数用来对一个数组进行排列,参数perm必须是正数1,....,k的一个排列,此处k是a下标的个数。
该函数得到一个与a相同大小的数组,原有的维被perm[j]给定的新维取代。
> a <- matrix(1:6,2,3)
> b <- aperm(a,c(2,1))
> a
[,1] [,2] [,3]
[1,] 1 3 5
[2,] 2 4 6
> b
[,1] [,2]
[1,] 1 2
[2,] 3 4
[3,] 5 6
>
其实这就是矩阵的倒置,可以直接使用函数t来实现转置
> a <- matrix(1:6,2,3)
> b <- t(a)
> a
[,1] [,2] [,3]
[1,] 1 3 5
[2,] 2 4 6
> b
[,1] [,2]
[1,] 1 2
[2,] 3 4
[3,] 5 6
>
5.7 专门的矩阵功能
矩阵仅仅是一个双下标的数组。R包含很多专门针对矩阵的数据操作。
如: t->转置函数 nrow->返回矩阵的行数 ncol->返回矩阵的列数
5.7.1 矩阵乘法
操作符: %*%
如: A、B是同样大小的矩阵
> A * B #是相应位置上的元素的乘积组成的矩阵
> A %*% B #是矩阵乘积 ????????执行出错?
crossprod 函数产生一个交叉乘积(cross product),即crossprod(X,Y)与t(X) %*% Y达成相同的效果,
但crossprod的效率更高。若省去第二个参数,相当于第一个参数与自己做运算。
diag 若参数是一个向量,则diag(v)返回一个由v的元素为对角元素的对角矩阵;
若参数是一个矩阵,diag(m)返回一个由M主对角元素组成的向量。
若参数只是一个数值,diag(k)则返回一个k X k的单位矩阵
> k <- 3
> diag(k)
[,1] [,2] [,3]
[1,] 1 0 0
[2,] 0 1 0
[3,] 0 0 1
>
> v <- c(1,2,3)
> diag(v)
[,1] [,2] [,3]
[1,] 1 0 0
[2,] 0 2 0
[3,] 0 0 3
> m <- matrix(1:6,2,3)
> diag(m)
[1] 1 4
5.7.2 线性方阵和矩阵的逆
求解线性方程是矩阵乘法的逆运算。
> b <- A %*% x
之后,若只有A和b被给出,则向量x是线性方程的解。在R中
> solve(A,b)
5.7.3 特征值和特征向量
eigen(Sm) 返回一个对称矩阵的特征值和特征向量。其结果是有名为values和vectors的两部分组成的列表。
> sm <- diag(v)
> sm
[,1] [,2] [,3]
[1,] 1 0 0
[2,] 0 2 0
[3,] 0 0 3
> eigen(sm)
$values
[1] 3 2 1
$vectors
[,1] [,2] [,3]
[1,] 0 0 1
[2,] 0 1 0
[3,] 1 0 0
>
5.8 奇异值分解与行列式
5.9 最小二乘拟合及QR分解
lsfit() 函数返回由最小二乘拟合的结果组成的列表。
>ans <- lsfit(X,y) #其结果返回最小二乘拟合的结果,其中y是观测值向量,X为设计矩阵。
.........
5.10 构建分区矩阵,cbind()和rbind()
cbind 按照列(水平方向)的方式将矩阵连接到一起。
rbind 按照行(垂直方向)的方式将矩阵连接到一起。
> x <- cbind(1,2,3)
> y <- rbind(1,2,3)
> x
[,1] [,2] [,3]
[1,] 1 2 3
> y
[,1]
[1,] 1
[2,] 2
[3,] 3
>
5.11 连接函数c(),针对数组的应用
cbind和rbind是具有dim属性的连接函数,而c函数则没有,它会清除所有的dim、dimnames属性。
> x <- cbind(1,2,3)
> x
[,1] [,2] [,3]
[1,] 1 2 3
> c(x)
[1] 1 2 3
>
5.12 由因子生成频数表
。。。。。。。。。???
列表和数据帧
6.1 列表
列表是有称做组件的有序对象集合构成的对象。(列表其实就是一种映射关系)
组件并不要求他们是相同模式或类型。一个列表可以包含数值向量,逻辑值,矩阵,复值向量,字符数组和函数等等。
> lst <- list(name = "Fred",wife = "Mary",no.child = 3,child.ages = c(12,15,17))
> lst
$name
[1] "Fred"
$wife
[1] "Mary"
$no.child
[1] 3
$child.ages
[1] 12 15 17
>
访问组件的方式:
1)组件是被编号了的,可以通过编号来指定列表的组件。使用[[1]]双中括号来引用。
> lst[[1]] #编号从1开始
[1] "Fred"
> lst[[4]]
[1] 12 15 17
>
2)列表的组件还可以通过组件的名字来引用,如:(listname$component name)
> lst$name #组件的名称可以缩写,可缩写的程度是只要能令组件被唯一识别就行,如:lst$na
[1] "Fred"
>
3)在双层方括号中使用列表组件的名称来引用
> lst[["name"]] #这样使用,测试过,组件名称不能使用缩写
[1] "Fred"
length 函数可以返回列表组件的个数(即长度)。
6.2 构建和修改列表
list 函数从现有的对象中建立新的列表。(组件的名称可以被省略,此时组件将只是被编号)
也可以通过制定额外组件的方式来扩展列表。
> lst["addrs"] <- "hangzhou"
6.2.1 连接列表(c函数)
c 函数的参数为列表时,其结果也是一个模式为列表的对象,由参数中的列表作为组件依次连接而成。
> list.A <- c(1,2)
> list.B <- "hhaha"
> list.C <- list(3,4,5)
> list.ABC <- list(list.A, list.B ,list.C)
> list.ABC
[[1]]
[1] 1 2
[[2]]
[1] "hhaha"
[[3]]
[[3]][[1]]
[1] 3
[[3]][[2]]
[1] 4
[[3]][[3]]
[1] 5
6.3 数据帧
数据帧是类别为"data.frame"的列表。
下面对列表的限制对数据帧也有效:
1) 组件必须是向量(数值型,字符形,逻辑型),因子,数值矩阵,列表,或其他数据帧
2) 矩阵,列表,数据帧向新数据帧提供的变量数分别等于它们的列数,元素数和变量数
3) 数值向量,逻辑值和因子在数据帧中保持不变,字符向量将被强制转化为因子,其水平是字符向量中所出现的值。
4) 数据帧中作为变量的向量结构必须具有相同的长度,而矩阵结构应当具有相同的行大小
6.3.1 创建数据帧
1)data.frame 对于满足数据帧的列(组件)限制的对象,可以通过函数data.frame来构建数据帧。
2)as.data.frame 如果一个列表的组件与数据帧的限制一致,该列表可以同个这个函数来强制转化为一个数据帧。
3)read.table 最简单的方法,是使用该函数从外部文件中读取整个数据帧。
> dataframe <- as.data.frame(lst)
> dataframe
name wife no.child child.ages addrs
1 Fred Mary 3 12 hangzhou
2 Fred Mary 3 15 hangzhou
3 Fred Mary 3 17 hangzhou
>
6.3.2 attach()与detach()
标记$,在组件中使用不是非常方便。可以有替代的attach方法是列表或者数据帧的组件暂时像变量一样可见。
> lst <- list(name = "Fred",wife = "Mary",no.child = 3,child.ages = c(12,15,17))
> lst
$name
[1] "Fred"
$wife
[1] "Mary"
$no.child
[1] 3
$child.ages
[1] 12 15 17
> attach(lst)
> name
[1] "Fred"
> wife
[1] "Mary"
> no.child
[1] 3
> child.ages
[1] 12 15 17
>
使用attach的方法,得到的来自列表和数据帧的变量仅在他们自己的权限范围内有效。也就是若对其变量的值进行改变,
并不会影响原来列表和数据帧的值,不会进行覆盖。
若需要对数据帧本身做永久的改变的话,最简单的方式还是得用$标记。
数据帧被覆盖完之后,此时attach得到的变量不会进行更新,得先detach,再重新挂接(attach),才可见。
(若已经某组件名称的变量,则attach将会发生错误)
attach: 1)需保证变量的唯一性 2)访问数据前,首先执行detach命令
6.3.3 管理搜索路径
search 函数将显示目前的搜索路径。对于用来跟踪已挂接或已卸载的数据帧和列表(以及功能包)是比较有用的。
ls()(或objects())命令可以用来检查搜索路径任意位置上的内容
从文中读取数据
7.1 函数read.tanle()
直接将整个数据帧读出,所有文件需符合特定的格式:
1)第一行提供数据帧的每个变量的名称
2)每一行包含一个行标号(必须是在第一个位置)和其他各变量的值
(若文件的第一行所包含的项目比第二行少,也认为是有效的。)
如:
Price Floor Area Rooms Age Cent.heat
01 52.00 111.0 830 5 6.2 no
02 54.75 128.0 710 5 7.5 no
> HousePrice <- read.table("houses.data")
此外,可以省略行标号,使用默认的行标号
Price Floor Area Rooms Age Cent.heat
52.00 111.0 830 5 6.2 no
54.75 128.0 710 5 7.5 no
> HousePrice <- read.table("houses.data", header=TRUE)
#选项header=TRUE说明文件的第一行是表头行,由此可知文件的格式中不包
括行标号。
7.2 函数scan()
从键盘或文件中读取数据,并存入向量或者列表中。
>inp <- scan(file,what)
第一个参数是文件名,若为空,则从键盘读入数据。(键盘输入时,结束输入是可以用Ctrl+Z,或者输入一个空格)。
第二个参数用于确定读入数据的模式。如:list("",0,0)指定读入到列表中,列表有三项,且列表第一项是字符型,
第二三项是数值型。若为0,则指定读入到一个数值向量中,若为""则指定读入到字符向量中。
> inp <- scan("",0)
1: 1000
2: 2000
3:
Read 2 items
> inp
[1] 1000 2000
> inp <- scan("","")
1: hello
2: world
3:
Read 2 items
> inp
[1] "hello" "world"
> inp <- scan("",list("",0,0))
1: "hello" 100 200
2:
Read 1 record
> inp
[[1]]
[1] "hello"
[[2]]
[1] 100
[[3]]
[1] 200
>
7.3 内建数据集的存取
内建数据集必须通过data函数载入。
data() #获取基本系统提供的数据集列表
data(infert) #载入名为infert的数据集
7.3.1 从其他R功能包中载入数据
如:
data(package="nls")
data(Puromycin, package="nls") #载入nls数据包 Puromycin数据集
library(nls) #挂接nls功能包,若nls包不存在,则出错
data() #查看数据集
data(Puromycin) #载入Puromycin数据集
7.4 编辑数据
在使用一个数据帧或矩阵时,edit提供了一个独立的工作表式编辑环境。
>xnew <- edit(xold) #对数据集xold进行编辑。并在完成时
概率分布 ??????
8.1 R--作为一个统计表的集合
R提供了一套完整的统计表集合。函数可以对累积分布函数P(X<=x),概率密度函数,分位函数求值,并根据分布进行模拟。
8.2 检测数据集合的分布
函数summary和fivenum这两个有轻微差异的摘要,函数stem可以将数值显示出来
(茎叶图"stem and leaf plot")
hist绘制直方图。
。。。。。。。
8.3 单样本和两样本检验
对两个样本的各方面进行比较,功能包ctest。
语句组、循环和条件操作
9.1 表达式语句组
R语言是一种表达式语言,也就是说其命令类型只有函数或表达式,并由它们返回一个结果。命令可以通过花括号来分组。
9.2 控制语句
9.2.1 条件执行:if语句
>if (exp_1) exp_2 else exp_3
if/else结构的向量版本是函数ifelse,其形式为ifelse (condition,a,b),产生函数结果的规则是:如果
condition[i]为真,对应a[i]元素,反之对应b[i]元素。
9.2.2 重复执行:for循环,repeat 和 while
>for (name in exp_1) exp_2
name是循环变量,exp_1是一个向量表达式,而exp_2经常是一个表达式语句组,其中的子表达式仅仅以形式名称(dummy name)
进行操作,和语句组外表达式的名称无关。exp_2随着name一次取exp_1结果向量的值而被多次重复运行。
> lst <- c(1,2,3,4)
> lst
[1] 1 2 3 4
> for (i in lst){
+ print(lst[i])
+ }
[1] 1
[1] 2
[1] 3
[1] 4
>
循环功能:
>repeat(exp)
>while (condition) exp
break语句可以用来中断任何循环,next语句可以中止一个特定的循环,跳至下一个。
(清屏 ctrl+l)
函数
函数的定义需要通过下面这种形式的赋值:
函数的定义:
>name <- function(arg_1,arg_2,...) exp
函数的调用:
>name(exp_1,exp_2,...)
10.1 示例
> add <- function(d1,d2){ #定义函数名
+ d <- d1 + d2; #两数值相加
+ d #返回值
+ }
> d1 <- 100
> d2 <- 200
> d <- add(d1,d2) #测试,调用函数
> d
[1] 300
>
10.2 定义新的二元操作符
将函数定义二元操作符:
>"%!%" <- function(x,y){...} #注意使用引号
之后就可以通过x%!%y的方式来使用函数。
例如之前使用过的 矩阵乘法运算符 %*% 和 矩阵外积运算符 %o% 也是这种定义方式。
10.3 指定的参数默认值
在定义函数的参数时,给出其初始值
如:
add <- function(d1,d2 = 200){...}
10.4 参数'...'
将一个函数的参数传递给另外一个函数。?????????
10.5 函数内才赋值
在函数内完成的任何一般赋值操作都是局部和临时的,当函数退出后就丢失。
若需要在函数内进行全局和永久的赋值,则需要用到“超赋值”操作符,<<-或者函数assign()
10.6 更高级的使用
10.7 范畴(scope)
函数主体内出现的标识(SYMBOL)可以被分为3类:正式参数、局部变量和自由变量。
正式参数:是出现在函数参数列表中的参数 ##形参
局部变量:由表达式求值过程中决定的变量
自由变量:即不是正式参数也不是局部变量的变量,在赋值之后将变为局部变量
> f <- function(x){
+ y <- 2*x
+ print(x) #正式参数
+ print(y) #局部变量
+ print(z) #自由变量
+ z <- 200
+ print(z) #变为局部变量
+ }
> z <- 2
> f(2)
[1] 2
[1] 4
[1] 2
[1] 200
> z
[1] 2
10.8 定制环境
R包含一个基础初始文件(SITE INITIALIZATION FILE),而且每个目录下可以有它们自己特定的初始文件。
最后还可以使用特殊的函数.First和.Last。
基础初始文件的位置是由R_PROFILE环境变量所决定的。
如果这个变量没有被设定,则R根目录下子目录‘etc’将被使用。这个文件中包含了每次R
启动时都会执行的命令。
此外一个名为'.Rprofile'的个人配置文件可以被置于任意一个目录下。如果R在该
目录下被调用,这个配置文件就会使用。如果在启动目录下没有找到‘.Rprofile’文件,那么
R就在用户的根目录下找'.Rprofile',并使用这个文件。
在两个配置文件之中或者'.RData'映像中,任何名为.First()的函数都具有特殊的意义。它将在R
任务的开始处被自动执行。
被执行的顺序是'Rprofile.site'、'.Rprofile'、'.RData',之后是.First()。后面文件的定义会
覆盖前面文件中的定义。