1、实验目的实验目的实验内容实验内容学习学习S语言中语言中离散变量、混合数据的表示方法的表示方法1 1、数据表示方法、数据表示方法2 2、应用实例、应用实例3 3、实验作业、实验作业因子、列表、数据框因子、列表、数据框因子和有序因子 统计中的变量重要类别: 区间变量和名义变量、有序变量。 区间变量取连续的数值,可以进行求和、平均等运算。 名义变量和有序变量取离散值,既可用数值代表也可用字符型值,其具体数值没有数量意义,不能用于加减乘除计算而只能用来分类或者计数。名义变量比如性别、省份、职业,有序变量比如班级名次。 因为离散变量有各种不同表示方法,在S中为统一起见使用因子(factor)来表示这种分
2、类变量。还提供了有序因子(ordered factor)来表示有序变量。 因子是一种特殊的字符型向量,其中每一个元素取一组离散值中的一个,而因子对象有一个特殊属性levels表示这组离散值(用字符串表示)。例如: x y y 1 男 女 男 男 女 Levels: 男 女 函数factor()用来把一个向量编码成为一个因子。一般形式为:factor(x, levels = sort(unique(x), na.last = TRUE), labels, exclude = NA, ordered = FALSE) 可以自行指定各离散取值(水平levels),不指定时由x的不同值来求得。 lab
3、els可以用来指定各水平的标签,不指定时用各离散取值的对应字符串。 exclude参数用来指定要转换为缺失值(NA)的元素值集合。如果指定了levels,则因子的第i个元素当它等于水平中第j个时元素值取“j”,如果它的值没有出现在levels中则对应因子元素值取NA。 ordered取真值时表示因子水平是有次序的(按编码次序)。 可以用is.factor()检验对象是否因子,用as.factor()把一个向量转换成一个因子。 x=c(1,0,1,1,0) y=factor(x,levels=sort(unique(x),decreasing=T),labels=c(男, 女),exclude=
4、NA,order=F) y1 男 女 男 男 女 Levels: 男 女 x=c(1,0,1,1,0,2)y=factor(x,levels=c(1,0),labels=c(男, 女),exclude=NA,order=F) y1 男 女 男 男 女 Levels: 男 女 因子的基本统计是频数统计,用函数table()来计数。例如, sex = factor(c(男, 女, 男, 男, 女) res.tab res.tab 男 女 3 2 表示男性3人,女性2人。table()的结果是一个带元素名的向量,元素名为因子水平,元素值为该水平的出现频数。 S的结果除了可以显示外,本身都是S对象(如
5、这里的向量结果),可以很方便地进一步处理。 可以用两个或多个因子进行交叉分类。比如,性别(sex)和职业(job)交叉分组可以用table(sex, job)来统计每一交叉类的频数,结果为一个矩阵,矩阵带有行名和列名,分别为两个因子的各水平名。 因子可以用来作为另外的同长度变量的分类变量。比如,假设上面的sex是5个学生的性别,而 h tapply(h, sex, mean) 可以求按性别分类的身高平均值。 这样用一个等长的因子向量对一个数值向量分组的办法叫做不规则数组(ragged array)。后面我们还可以看到更多的因子的应用。实验目的实验目的学习学习S语言中数据语言中数据列表列表列表(
6、列表(list) 列表定义列表定义 列表是一种特别的对象集合,它的元素也由序号(下标)区分,但是各元素的类型可以是任意对象,不同元素不必是同一类型。元素本身允许是其它复杂数据类型,比如,列表的一个元素也允许是列表。 列表元素用“列表名下标”的格式引用。 但是,列表不同于向量,我们每次只能引用一个元素,如rec1:2的用法是不允许的。 注意:“列表名下标”或“列表名下标范围”的用法也是合法的,但其意义与用两重括号的记法完全不同,两重记号取出列表的一个元素,结果与该元素类型相同,如果使用一重括号,则结果是列表的一个子列表(结果类型仍为列表)。 rec = list(name=李明, age=30,
7、 scores=c(85, 76, 90) rec $name 1 李明 $age 1 30 $scores 1 85 76 90 rec1 $name 1 李明 rec1 1 李明 rec2 $age 1 30 rec2 1 30 rec3 $scores 1 85 76 90 rec3 1 85 76 90 rec31:21 85 76 在定义列表时如果指定了元素的名字(如rec中的name,age,scores),则引用列表元素还可以用它的名字作为下标,格式为“列表名元素名”,如: recage 1 30 另一种格式是“列表名$元素名”,如: rec$age 1 30 其中“元素名”可以
8、简写到与其它元素名能够区分的最短程度,比如“rec$s”可以代表 “rec$score”。 这种写法方便了交互运行,编写程序时一般不用简写以免降低程序的可读性。 使用元素名的引用方法可以让我们不必记住某一个下标代表那一个元素,而直接用易记的元素名来引用元素。事实上,已知向量和矩阵也可以指定元素名、行名、列名。 定义列表使用list()函数,每一个自变量变成列表的一个元素,自变量可以用“名字值”的方式给出,即给出列表元素名。 自变量的值被复制到列表元素中,自变量如果是变量并不会与该列表元素建立关系(改变该列表元素不会改变自变量的值)。修改列表 列表的元素可以修改,只要把元素引用赋值即可。 如:
9、rec$age rec$age rec$sex rec6 rec rec$sex rec6 rec $name 1 李明 $age 1 30 $scores 1 85 76 90 $sex 1 男 5 NULL 6 1 161 第五号元素因为没有定义所有其值是“NULL”,这是空对象的记号。 如果rec是一个向量,则其空元素为“NA”,这是缺失值的记号。从这里我们也可以体会“NULL”与“NA”的区别。 几个列表可以用连接函数c()连接起来,结果仍为一个列表,其元素为各自变量的列表元素。如: list.ABC ev=eigen(1:3)%o%(1:3) ev $values 1 1.40000
10、0e+01 9.176554e-16 -1.023391e-15 $vectors ,1 ,2 ,3 1, -0.2672612 0.6067775 0.7485937 2, -0.5345225 0.5530299 -0.6390960 3, -0.8017837 -0.5709457 0.1765328特征向量按矩阵存放,每一列为一个特征特征向量。二、奇异值分解及行列式二、奇异值分解及行列式函数函数svd()进行奇异值分解进行奇异值分解自学自学三、最小二乘拟合与三、最小二乘拟合与QR分解分解 函数lsfit(x,y)返回最小二乘拟合的结果。最小二乘的模型为线性模型 lsfit(x,y)的第
11、一个参数x为模型中的设计阵 ,第二个参数y为模型中的因变量y(可以是一个向量也可以是一个矩阵),返回一个列表,成员coefficients为上面模型的 最小二乘系数,成员residuals为拟合残差,成员intercept用来指示是否有截距项,成员qr为设计阵 的QR分解,它本身也是一个列表。YX三、最小二乘拟合与三、最小二乘拟合与QR分解分解 关于最小二乘拟合还可参见ls.diag() 函数(查看帮助)。 函数qr(x)返回x的QR分解结果。矩阵X的QR分解为X=Q*R ,Q为对角线元素都等于1的下三角阵,R为上三角阵。 函数结果为一个列表,成员qr 为一个矩阵,其上三角部分(包括对角线)分
12、解的R,其下三角部分(不包括对角线)为分解的Q。其它成员为一些辅助信息。 x=rbind(c(1,2,3),c(4,5,6),c(7,8,9) y=qr(x) y qr.R(y) qr.Q(y) qr.Q(y)%*%qr.R(y) x=rbind(c(1,2,3),c(4,5,6),c(7,8,9) y=qr(x) y$qr ,1 ,2 ,31, -8.1240384 -9.6011363 -1.107823e+012, 0.4923660 0.9045340 1.809068e+003, 0.8616404 0.9954736 -2.220446e-16$rank1 2$qraux1 1.1
13、23091e+00 1.095039e+00 2.220446e-16$pivot1 1 2 3attr(,class)1 qr qr.R(y) ,1 ,2 ,31, -8.124038 -9.601136 -1.107823e+012, 0.000000 0.904534 1.809068e+003, 0.000000 0.000000 -2.220446e-16 qr.Q(y) ,1 ,2 ,31, -0.1230915 0.9045340 0.40824832, -0.4923660 0.3015113 -0.81649663, -0.8616404 -0.3015113 0.40824
14、83 qr.Q(y)%*%qr.R(y) ,1 ,2 ,31, 1 2 32, 4 5 63, 7 8 9数据框(data.frame) 数据框是S中类似SAS数据集的一种数据结构。它通常是矩阵形式的数据,但矩阵各列可以是不同类型的。数据框每列是一个变量,每行是一个观测。 数据框有更一般的定义。它是一种特殊的列表对象,有一个值为“data.frame”的class 属性,各列表成员必须是向量(数值型、字符型、逻辑型)、因子、数值型矩阵、列表,或其它数据框。向量、因子成员为数据框提供一个变量,如果向量非数值型则会被强制转换为因子,而矩阵、列表、数据框这样的成员为新数据框提供了和其列数、成员数、变
15、量数相同个数的变量。作为数据框变量的向量、因子或矩阵必须具有相同的长度(行数)。 尽管如此,我们一般还是可以把数据框看作是一种推广了的矩阵,它可以用矩阵形式显示,可以用对矩阵的下标引用方法来引用其元素或子集。数据框生成数据框生成 数据框可以用data.frame()函数生成,其用法与list()函数相同,各自变量变成数据框的成分,自变量可以命名,成为变量名。例如: d=data.frame(name=c(赵, 钱, 孙, 李, 王),age=c(20,21,22,21,20),height=c(170,171,175,165,181),gender=c(男, 女, 男, 女, 男 ) d 如果
16、一个列表的各个成分满足数据框成分的要求,它可以用as.data.frame()函数强制转换为数据框。比如,上面的d如果先用list()函数定义成了一个列表,就可以强制成为一个数据框。 一个矩阵可以用data.frame()转换为一个数据框,如果它原来有列名则其列名被作为数据框的变量名,否则系统自动为矩阵的各列起一个变量名(如X1,X2)。 d name age height gender 1 赵 20 170 男 2 钱 21 171 女 3 孙 22 175 男 4 李 21 165 女 5 王 20 181 男 d1 name 1 赵 2 钱 3 孙 4 李 5 王 d1 1 赵 钱 孙
17、李 王 Levels: 李 钱 孙 王 赵 d22:3 1 21 22数据框引用 引用数据框元素的方法与引用矩阵元素的方法相同,可以使用下标或下标向量,也可以使用名字或名字向量。如d1:2, 2:3。数据框的各变量也可以用按列表引用(即用双括号 或$符号引用)。 数据框的变量名由属性names定义,此属性一定是非空的。数据框的各行也可以定义名字,可以用rownames属性定义。如: names(d) 1 name age height gender rownames(d) 1 1 2 3 4 5 table(d4) 男 女 3 2 table(d4)男 女 3 2 tapply(d3,d4,
18、mean) 男 女 175.3333 168.0000 tapply(d3,d4, mean) 错误在tapply(d3, d4, mean) : 变元的长度必需相同 d3/d2 1 8.500000 8.142857 7.954545 7.857143 9.050000attach()函数 数据框的主要用途是保存统计建模需要的数据。S的统计建模功能都需要以数据框为输入数据。我们也可以把数据框当成一种矩阵来处理。 在使用数据框的变量时可以用“数据框名$变量名”的记法。但是,这样使用较麻烦,S提供了attach()函数可以把数据框“连接”入当前的名字空间。例如, attach(d) r d$r
19、cat(i = , i, n) 注意使用cat()时要自己加上换行符“n”。它把各项转换成字符串,中间隔以空格连接起来,然后显示。 如果要使用自定义的分隔符,可以用sep=参数,例如: cat(c(AB, C), c(E, F), n, sep=) ABCEF cat()还可以指定一个参数file=给一个文件名,可以把结果写到指定的文件中,如: cat(i = , 1, n, file=c:/work/result.txt) 如果指定的文件已经存在则原来内容被覆盖。加上一个append=TRUE参数可以不覆盖原文件而是在文件末尾附加,这很适用于运行中的结果记录。 cat()函数和print()
20、都不具有很强的自定义格式功能,为此可以使用cat()与format() 函数配合实现。format()函数为一个数值向量找到一种共同的显示格式然后把向量转换为字符型。例如: format(c(1, 100, 10000) 1 1 100 10000 S-PLUS中的format()函数功能较强,具有较多的控制参数,请参见帮助。 R中目前format() 函数功能仍较弱,但R有一个formatC函数可以提供类似C语言的printf格式功能。formatC对输入向量的每一个元素单独进行格式转换而不生成统一格式,例如: formatC(c(1, 10000) 1 1 1e+004 在formatC(
21、)函数中可以用format=参数指定C格式类型,如“d”(整数),“f”(定点实数),“e”(科学记数法),“E”, “g”(选择位数较少的输出格式),“G”, “fg”(定点实数但用digits 指定有效位数),“s”(字符串)。 可以用width指定输出宽度,用digits指定有效位数(格式为e,E,g,G,fg时)或小数点后位数(格式为f)时。可以用flag参数指定一个输出选项字符串,字符串中有-表示输出左对齐,有0表示左空白用0填充,有+表示要输出正负号,等等。例如,我们有一个矩阵da中保存了三个日期的年、月、日: da ,1 ,2 ,3 1, 99 1 3 2, 96 11 93,
22、65 5 18 为了输出这三个日期,可以用apply函数指定对每一行作用一个输出函数,此输出函数利用cat()和formatC来控制: apply(da, 1, function(r) cat(formatC(r1, format=d, width=2, flag=0), -, formatC(r2, format=d, width=2, flag=0), -, formatC(r3, format=d, width=2, flag=0), n, sep=) 99-01-03 96-11-09 65-05-18 NULL 这里我们知道apply函数第一个参数指定了一个矩阵,第二个参数说明对行操
23、作还是对列操作,第三个参数是一个函数,这里我们使用了直接定义一个函数作为参数的办法。输出结果中多了一个NULL函数,这是因为我们在交互运行,apply的结果作为一个表达式的值(NULL )会被显示出来。 为避免显示,可以把结果赋给一个临时变量名,或者把整个表达式作为invisible() 函数的参数,这时不显示表达式值。 S的输出缺省显示在交互窗口。可以用sink()函数指定一个文件以把后续的输出转向到这个文件,并可用append参数指定是否要在文件末尾附加: sink(“E:/work/result.txt, append=TRUE) ls() d sink() 调用无参数的sink()把输
24、出恢复到交互窗口。 write(t(x),file=文件名,nol=nol(x)把一个矩阵X输出到文件中,把X转置后输出因为R中矩阵是列优先的,如果不转置则输出是按列输出的。如果不指定列数则缺省使用5列。文件名缺省用data. write.table(x,file=文件名)把数据框X输出到文件中,输出包括变量名表头和行名。. cl = read.table(“E:/R/class.txt, as.is=c(1), + col.names=c(Name, Sex, Age, Height, Weight) cl输入输入 为了从外部文件读入一个数值型向量,S提供了scan()函数。如果指定了fil
25、e参数(也是第一参数),则从指定文件读入,缺省情况下读入一个数值向量,文件中各数据以空白分隔,读到文件尾为止。例如: cat(1:12, n, file=E:/work/result.txt) x y x x V1 V2 V3 1 Zhou 15 3 2 Li Ming 9 李明 3 Zhang 10.2 Wang 读入结果为数据框。 函数可以自动识别表列是数值型还是字符型,并在缺省情况下把字符型数据转换为因子(加上as.is=T可以保留字符型不转换)。 函数自动为数据框变量指定“V1 ”、“V2”这样的变量名,指定“1”、“2”这样的行名。可以用col.names参数指定一个字符型向量作为数
26、据框的变量名,用row.names参数指定一个字符型向量作为数据框的行名。 read.table()可以读入带有表头的文件,只要加上header=TRUE参数即可。可以用sep 参数指定表行各项的分隔符。例如,为了读入如下带有表头的逗号分隔文件E:d.csv: Name,score, cn Zhou,15,3 Li Ming, 9, 李明 Zhang, 10.2, Wang 使用如下语句: x=read.table(E:/d.csv, header=T, sep=,) x Name score cn 1 Zhou 15.0 3 2 Li Ming 9.0 李明 3 Zhang 10.2 Wan
27、g 其它一些用法见帮助。 cl =read.table(E:/R/class.txt, as.is=c(1), col.names=c(Name, Sex, Age, Height, Weight); cat(names(cl),names(cl); class.data=read.table(E:/R/class.csv,header=T,sep=,); cat(names(class.data),names(class.data); Edata = read.table(E:/R/Employee data.csv,header=T,sep=,) cat(names(Edata),name
28、s(Edata); read.spss package:foreign R Documentation Read an SPSS data file Description: read.spss reads a file stored by the SPSS save and export commands and returns a list. Usage: read.spss(file, use.value.labels=TRUE, to.data.frame=FALSE, max.value.labels=Inf, trim.factor.names=FALSE) Arguments:
29、file: character variable with the name of the file to read. use.value.labels: Convert variables with value labels into R factors with those levels? to.data.frame: return a data frame? max.value.labels: Only variables with at most this many unique values will be converted to factors trim.factor.names
30、: Trim trailing spaces from factor levels? Details: This uses modified code from the PSPP project for reading the SPSS formats. Occasionally in SPSS value labels will be added to some values of a continuous variable (eg to distinguish different types of missing data), and you will not want these var
31、iables converted to factors. By setting max.val.labels you can specify that variables with a large number of distinct values are not converted to factors even if they have value labels. In addition, variables will not be converted to factors if there are non-missing values that have no value label.
32、The value labels are then returned in the value.labels attribute of the variable. If SPSS variable labels are present, they are returned as the variable.labels attribute of the answer. Fixed length strings (including value labels) are padded on the right with spaces by SPSS, and so are read that way
33、 by R. See the examples for sub for ways to remove trailing spaces in string data. Value: A list (or data frame) with one component for each variable in the saved data set. Note: If SPSS value labels are converted to factors the underlying numerical codes will not in general be the same as the SPSS
34、numerical values, since the numerical codes in R are always 1,2,3,. Author(s): Saikat DebRoy Examples: # Not run: read.spss(datafile) # dont convert value labels to factor levels read.spss(datafile,use.value.labels=FALSE) # convert value labels to factors for variables with at most # ten distinct va
35、lues. read.spss(datafile,max.val.labels=10) # End(Not run)实验目的实验目的实验内容实验内容学习学习S语言中程序设计方法语言中程序设计方法1 1、程序设计程序设计方法方法2 2、应用实例、应用实例3 3、实验作业、实验作业程序设计程序设计程序控制结构 ?是一个表达式语言,其任何一个语句都可以看成是一个表达式。表达式之间以分号分隔或用换行分隔。表达式可以续行,只要前一行不是完整表达式(比如末尾是加减乘除等运算符,或有未配对的括号)则下一行为上一行的继续。 若干个表达式可以放在一起组成一个复合表达式,作为一个表达式使用。组合用大括号表示,如:
36、 x x S语言也提供了其它高级程序语言共有的分支、循环等程序控制结构。 分支结构 分支结构包括if结构: if (条件) 表达式1 或 if (条件) 表达式1 else 表达式2 其中的“条件”为一个标量的真或假值,表达式可以是用大括号包围的复合表达式。有else 子句时一般写成: if(条件) 表达式组 else 表达式组 这样的写法可以使else不至于脱离前面的if。 例如,如果变量lambda为缺失值就给它赋一个缺省值,可用: if(is.na(lambda) lambda 0) & all(log(x)0) y 0) 1 else 0 当x是标量时这个定义是有效的,但是当自变量x是
37、一个向量时,比较的结果也是一个向量,这时条件无法使用。所以,这个分段函数应该这样编程: y= numeric(length(x) yx0 - 1 yx=0 - 0 有多个if语句时else与最近的一个配对。可以使用if . else if . else if . else .的多重判断结构表示多分支。多分支也可以使用switch()函数。循环结构 循环结构中常用的是for循环,是对一个向量或列表的逐次处理,格式为“for( name in values) 表达式”,如: for(i in seq(along=x) cat(x(, i, ) = , xi, n, sep=); s - s+xi;
38、 这个例子我们需要使用下标的值,所以用seq(along=x)生成了x的下标向量。 如果不需要下标的值,可以直接如此使用: for(xi in x) cat(xi, n) s x = numeric(364) for(i in 1:364) xi= 1 for(j in 0:(i-1) xi= xi * (365-i)/365 xi x for(n in 1:364) xn =1 - prod(365:(365-n+1)/365) 这段程序只用了1秒。注意不能直接去计算365!,这会超出数值表示范围。 另外要注意使用for(i in 1:n)格式的计数循环时要避免一个常见错误,即当n为零或负数
39、时1:n是一个从大到小的循环,而我们经常需要的是当n为零或负数时就不进入循环。为达到这一点,可以在循环外层判断循环结束值是否小于开始值。 while循环是在开始处判断循环条件的当型循环,如: While (b-aeps) c 0) b - c else a ls() 1 A Ai b cl cl.f fit1 g1 marks ns 10 p1 rec tmp.x x x1 x2 x3 y rm(x, x1, x2, x3) ls() 1 A Ai b cl cl.f fit1 g1 marks ns 10 p1 rec tmp.x y ls()可以指定一个pattern参数,此参数定义一个匹
40、配模式,只返回符合模式的对象名。模式格式是UNIX中grep的格式。比如,ls(pattern=tmp.)可以返回所有以“tmp.” 开头的对象名。 rm()可以指定一个名为list的参数给出要删除的对象名,所以rm(list=ls(pattern=“tmp.”) 可以删除所有以“tmp.”开头的对象名。 rm(list=ls() 删除所有对象。函数定义 S中函数定义的一般格式为“函数名= function(参数表) 表达式”。定义函数可以在命令行进行,例如 hello = function() cat(Hello, worldn) ; cat(n) ; hello function () c
41、at(Hello, worldn) ;cat(n) ; hello() Hello, world 函数体为一个复合表达式,各表达式的之间用换行或分号分开。不带括号调用函数显示函数定义,而不是调用函数。 在命令行输入函数程序很不方便修改,所以我们一般是打开一个其他的编辑程序(如Windows 的记事本),输入以上函数定义,保存文件,比如保存到了C:Rhello.R,我们就可以用 source(“E:/R/hello.R) 运行文件中的程序。实际上,用source()运行的程序不限于函数定义,任何S程序都可以用这种方式编好再运行,效果与在命令行直接输入是一样的。 对于一个已有定义的函数,可以用fi
42、x()函数来修改,如: fix(hello) 将打开一个编辑窗口显示函数的定义,修改后关闭窗口函数就被修改了。fix()调用的编辑程序缺省为记事本,可以用“options(editor=编辑程序名)”来指定自己喜欢的编辑程序。 函数可以带参数,可以返回值,例如: larger = function(x, y) y.is.bigger= (yx); xy.is.bigger = yy.is.bigger; x; 这个函数输入两个向量(相同长度)x和y,然后把x中比y对应元素小的元素替换为y中对应元素,返回y的值。S返回值为函数体的最后一个表达式的值,不需要使用return()函数。不过,也可以使
43、用“return( 对象)”函数从函数体返回调用者。参数(自变量) 函数可以带虚参数(形式自变量)。S函数调用方式很灵活,例如,如下函数: fsub =function(x, y) x-y 有两个虚参数x和y,我们用它计算10045,可以调用fsub(100,45),或fsub(x=100,y=45) ,或fsub(y=45, x=100),或fsub(y=45, 100)。即调用时实参与虚参可以按次序结合,也可以直接指定虚参名结合。实参先与指定了名字的虚参结合,没有指定名字的按次序与剩下的虚参结合。 函数在调用时可以不给出所有的实参,这需要在定义时为虚参指定缺省值。例如上面的函数改为: fs
44、ub = function(x, y=0) x-y 则调用时除了可以用以上的方式调用外还可以用fsub(100),fsub(x=100)等方式调用,只给出没有缺省值的实参。 即使没有给虚参指定缺省值也可以在调用时省略某个虚参,然后函数体内可以用missing() 函数判断此虚参是否有对应实参,如: trans = function(x, scale) if(!missing(scale) x = scale*x 此函数当给了scale的值时对自变量x乘以此值,否则保持原值。这种用法在其它语言中是极其少见的,S可以实现这一点是因为S的函数调用在用到参数的值时才去计算这个参数的值(称为“懒惰求值”
45、),所以可以在调用时缺少某些参数而不被拒绝。 S函数还可以有一个特殊的“.”虚参,表示所有不能匹配的实参,调用时如果有需要与其它虚参结合的实参必须用“虚参名”的格式引入。例如: f =function(.) for(x in list(.) cat(min(x), n) f(c(5,1,2), c(9, 4, 7) 1 4 作用域作用域 函数的虚参完全是按值传递的,改变虚参的值不能改变对应实参的值。例如: x = list(1, abc) x f =function(x) x2 f(x) x 函数体内的变量也是局部的,对函数体内的变量赋值当函数结束运行后变量值就删除了,不影响原来同名变量的值。
46、例如: x = 2 f = function()print(x) ; x= 20 f() 1 2 x 1 2 这个例子中原来有一个变量x值为2,函数中为变量x赋值20,但函数运行完后原来的x值并未变化。但是也要注意,函数中的显示函数调用时局部变量x还没有赋值,显示的是全局变量x 的值。这是这是S编程比较编程比较容易出问题的地方:你用到了一个局部变量的值,你容易出问题的地方:你用到了一个局部变量的值,你没有意识到这个局部变量还没有赋值,而程序却没有没有意识到这个局部变量还没有赋值,而程序却没有出错,因为这个变量已有全局定义。出错,因为这个变量已有全局定义。 程序调试 S-PLUS和R目前还不象其
47、它主流程序设计语言那样具有单步跟踪、设置断点、观察表达式等强劲的调试功能。调试复杂的S程序,可以用一些通用的程序调试方法,另外S也提供了一些调试用函数。 对任何程序语言,最基本的调试手段当然是在需要的地方显示变量的值。可以用print() 或cat()显示。例如,我们为了调试前面定义的larger()函数,可以显示两个自变量的值及中间变量的值: larger x); cat(y.is.bigger = , y.is.bigger, n) ;xy.is.bigger = yy.is.bigger x S提供了一个browser()函数,当调用时程序暂停,用户可以查看变量或表达式的值,还可以修改变
48、量。例如: larger= function(x, y) y.is.bigger x); browser() ;xy.is.bigger =yy.is.bigger; x ; 我们运行此程序: larger(c(1,5), c(2, 4, 9) 退出R的browser()菜单可用c(在S中用return())。在R的browser()状态下用n命令可以进入单步执行状态,用n或者回车可以继续,用c可以退出。 R提供了一个debug()函数,debug(f)可以打开对函数f()的调试,执行到函数f时自动进入单步执行的browser()菜单。用undebug(f)关闭调试。 Warning in y
49、 x : longer object length is not a multiple of shorter object length Called from: larger(c(1, 5), c(2, 4, 9) Browse1 y 1 2 4 9 Browse1 x 1 1 5 Browse1 yx Warning in y x : longer object length is not a multiple of shorter object length 1 TRUE FALSE TRUE Browse1 c Error: subscript (3) out of bounds, s
50、hould be at most 2 程序设计举例程序设计举例 设计S程序是很容易的,在初学时我们只要使用我们从一般程序设计中学来的知识并充分利用S中现成的各种算法及绘图函数就可以了。但是,如果要用S编制计算量较大的程序,或者程序需要发表,就需要注意一些S程序设计的技巧。 用S语言开发算法,最重要的一点是要记住S是一个向量语言,计算应该尽量通过向量、矩阵运算来进行,或者使用S提供的现成的函数,避免使用显式循环。显式循环会大大降低S的运算速度,因为S是解释执行的。 比如,考虑核回归问题。核回归是非参数回归的一种,假设变量 Y与变量 X之间的关系为:Liti15_1.R:n=1:10;x=sin(
侵权处理QQ:3464097650--上传资料QQ:3464097650
【声明】本站为“文档C2C交易模式”,即用户上传的文档直接卖给(下载)用户,本站只是网络空间服务平台,本站所有原创文档下载所得归上传人所有,如您发现上传作品侵犯了您的版权,请立刻联系我们并提供证据,我们将在3个工作日内予以改正。