内容提要
- 控制流
- 函数
选择结构
if
使用方法: 如果cond为真, 则执行statement
if (cond) statement
1 2
| x <- 10 if(x %% 2 == 0) print("Even")
|
if和else
使用方法: 如果cond为真, 则执行statement1, 否则执行statement2
if (cond) statement1 else statement2
1 2
| x <- 9 if(x %% 2 == 0) print("Even") else print("Odd")
|
if和else中需要注意的事项
- cond条件只能是长度为1的向量
- else必须和if在同一行(或和if的右大括号同一行)
1 2
| x <- 1:10 if(x %% 2 == 0) print("Even")
|
1 2
| ## Warning in if (x%%2 == 0) print("Even"): the condition has length > 1 and ## only the first element will be used
|
if和else不在同一行时
1 2 3
| x <- 9 if(x %% 2 == 0) print("Even") else print("Odd")
|
ifelse
为了解决if和else不能向量化的问题, 引入ifelse
使用方法: 当cond为真时, 执行statement1, 否则执行statement2
ifelse(cond,statement1,statement2)
1 2
| x <- 6:-4 ifelse(x >= 0, x, -x)
|
1
| ## [1] 6 5 4 3 2 1 0 1 2 3 4
|
多个分支: switch
1 2 3 4 5 6 7
| i <- "gamma" switch(i, beta = "You typed beta", alpha = "You typed alpha", gamma = "You typed gamma", delta = "You typed delta" )
|
1
| ## [1] "You typed gamma"
|
如果找不到任何值, 则switch返回NULL
循环
while
使用方法: 重复执行statement, 直到cond不为真为止
while(cond) statement
1 2
| i <- 5 while(i > 0) {print("Hi"); i <- i - 1}
|
1 2 3 4 5
| ## [1] "Hi" ## [1] "Hi" ## [1] "Hi" ## [1] "Hi" ## [1] "Hi"
|
repeat
使用方法: 重复执行statement, 直到cond不为真为止
repeat {statement if(cond) break}
1 2 3 4 5
| i <- 5 repeat{ print("Hi"); i <- i - 1 if(i <= 0) break }
|
1 2 3 4 5
| ## [1] "Hi" ## [1] "Hi" ## [1] "Hi" ## [1] "Hi" ## [1] "Hi"
|
for
使用方法: 重复执行statement, 直到var不在seq中为止
for(var in seq) statement
1 2 3
| x <- 0 for(i in 1:10) x <- x + i x
|
练习
- 生成斐波那契数列的前10项
- 生成斐波那契数列的所有不超过1000000的项
- 生成前1000个质数
- 找出最大数不超过100的所有勾股数组合
答案1
生成斐波那契数列的前10项
1 2 3 4 5
| x <- rep(1,10) for(i in 3:10){ x[i] <- x[i-1] + x[i-2] } x
|
1
| ## [1] 1 1 2 3 5 8 13 21 34 55
|
答案2
生成斐波那契数列的所有不超过1000000的项
1 2 3 4 5 6
| y <- rep(1,2);i <- 3 while(max(y) <= 1000000){ y[i] <- y[i-1] + y[i-2] i <- i + 1 } y[1:(length(y) - 1)]
|
1 2 3
| ## [1] 1 1 2 3 5 8 13 21 34 55 ## [11] 89 144 233 377 610 987 1597 2584 4181 6765 ## [21] 10946 17711 28657 46368 75025 121393 196418 317811 514229 832040
|
答案3
生成前1000个质数
1 2 3 4 5
| z <- 2;i <- 3 while(length(z) < 1000){ if(!any(i %% 2:(i-1) == 0)) z[length(z) + 1] <- i i <- i + 1 }
|
答案4
找出最大数不超过100的所有勾股数组合
1 2 3 4 5 6 7 8
| for(k in 1:100){ for(j in 1:k){ for(i in 1:j){ if(i^2 + j^2 == k^2) print(c(i,j,k)) } } }
|
函数
- 数学函数
- 统计函数
- 概率函数
- 字符处理函数
- 自定义函数
数学函数
- abs, sqrt, ceiling, floor
- trunc, round(x, digits = n), signif(x, digits = n)
- cos, sin, tan
- acos, asin, atan
- cosh, sinh, tanh
- log, log10, log(x, base = n)
数学函数示例
1
| ## [1] 1.000000 1.414214 1.732051 2.000000
|
1
| c(trunc(5.99), trunc(-0.9))
|
1
| round(3.475, digits = 2)
|
1
| signif(3.475, digits = 2)
|
1
| ## [1] 1.047198 1.047198
|
1
| ## [1] 0.5235988 0.5235988
|
1
| ## [1] 0.7853982 0.7853982
|
统计函数
- mean, median, quantile
- sd, var
- sum, diff
- min, max, range
- scale
统计函数示例
1
| mean(c(1:9, NA), na.rm = T)
|
1 2
| ## 0% 25% 50% 75% 100% ## 1.00 25.75 50.50 75.25 100.00
|
1
| quantile(1:100, probs = c(0.3,0.7))
|
1 2
| ## 30% 70% ## 30.7 70.3
|
1
| quantile(1:100, probs = seq(0,1,0.1))
|
1 2
| ## 0% 10% 20% 30% 40% 50% 60% 70% 80% 90% 100% ## 1.0 10.9 20.8 30.7 40.6 50.5 60.4 70.3 80.2 90.1 100.0
|
1
| diff(c(1,5,12,28), lag = 1)
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| ## [,1] ## [1,] -1.4863011 ## [2,] -1.1560120 ## [3,] -0.8257228 ## [4,] -0.4954337 ## [5,] -0.1651446 ## [6,] 0.1651446 ## [7,] 0.4954337 ## [8,] 0.8257228 ## [9,] 1.1560120 ## [10,] 1.4863011 ## attr(,"scaled:center") ## [1] 5.5 ## attr(,"scaled:scale") ## [1] 3.02765
|
概率函数
概率函数形式:
[dpqr]distribution_abbreviation()
- d = 密度函数 density
- p = 分布函数 distribution function
- q = 分位数函数 quantile function
- r = 生成随机数
概率分布缩写


密度函数
1 2 3
| x <- seq(-3,3,length.out = 100) y <- dnorm(x) plot(x,y,type = "l")
|
1 2 3
| x <- 1:30; plot(x, dpois(x, lambda = 1), type = "l") lines(x, dpois(x, lambda = 5), col = "blue"); lines(x, dpois(x, lambda = 10), col = "red")
|
分布函数
1 2 3
| x <- seq(-3,3,length.out = 100) y <- pnorm(x) plot(x,y,type = "l")
|
练习
请作下图, 比较t分布(df = 1 和 3)和标准正态分布的密度曲线(使用text()添加文字)
分位数函数
分位数函数和分布函数互相联系
生成随机数
1
| x <- rnorm(100); mean(x); hist(x)
|
Reproducible Research
1
| ## [1] -0.3628155 0.4724650 0.6511996 0.5244914 -1.0902893 0.4615401
|
1
| ## [1] 1.44724163 1.25659218 0.91141674 0.65039449 0.49668000 -0.06138254
|
1
| set.seed(123); x <- rnorm(100);head(x)
|
1
| ## [1] -0.56047565 -0.23017749 1.55870831 0.07050839 0.12928774 1.71506499
|
1
| set.seed(123); x <- rnorm(100);head(x)
|
1
| ## [1] -0.56047565 -0.23017749 1.55870831 0.07050839 0.12928774 1.71506499
|
验证分布数字特征
1 2 3
| set.seed(123) x <- rbinom(100, size = 40, prob = 0.5) mean(x)
|
1 2
| y <- runif(100, min = 0, max = 1) mean(y)
|
字符处理函数
- nchar
- substr
- grep
- sub
- strsplit
- paste
- toupper, tolower
nchar
计算字符串长度
1 2
| x <- c("ab","cde","fghij") length(x)
|
substr
提取或替换一个字符向量中的子串
1 2
| x <- "abcdef" substr(x,2,4)
|
1 2
| substr(x,2,4) <- "22222" x
|
grep
搜索子串, 可以使用正则表达式
1 2
| txt <- c("arm","foot","lefroo", "bafoobar") grep("foo", txt)
|
1
| ## [1] "foot" "bafoobar"
|
sub和gsub
sub and gsub perform replacement of the first and all matches respectively.
1 2
| str <- "Now is the time " sub(" ", "", str)
|
1
| ## [1] "Nowis the time "
|
strsplit
对字符串进行分解
1 2
| x <- c(as = "asfef", qu = "qwerty", "yuiop[", "stuff.blah.yech") strsplit(x, "e")
|
1 2 3 4 5 6 7 8 9 10 11
| ## $as ## [1] "asf" "f" ## ## $qu ## [1] "qw" "rty" ## ## [[3]] ## [1] "yuiop[" ## ## [[4]] ## [1] "stuff.blah.y" "ch"
|
paste
1
| paste("x", 1:3, sep = "")
|
1
| paste("x", 1:3, sep = "M")
|
1
| ## [1] "xM1" "xM2" "xM3"
|
1
| paste("Today is", date())
|
1
| ## [1] "Today is Sun Nov 15 14:36:28 2015"
|
大小写转换
1 2
| x <- "MiXeD cAsE 123" toupper(x)
|
自定义函数
myfunction <- function(arg1, arg2, …){
statements
return(object)
}
- arg可以有默认值
- 如果没有显式的return语句, 则最后一个表达式的值将返回
- 如果有return, 则遇到return时函数结束, 后面的代码不再执行
自定义函数举例
输入直角三角形的直角边长度, 输出斜边长度
1 2 3 4
| hypotenuse <- function(x, y){ sqrt(x^2 + y^2) } hypotenuse(3,4)
|
函数的嵌套定义
1 2 3 4 5 6 7 8 9
| f <- function(x){ y <- 1 g <- function(x){ (x + y)/2 } g(x) }
f(3)
|
练习
输入一个正整数n(n > 3), 输出斐波那契数列的前n项
1
| ## [1] 1 1 2 3 5 8 13 21 34 55 89 144 233 377 610
|
练习
输入一个正整数n(n > 3), 输出斐波那契数列的前n项
1 2 3 4 5 6 7 8
| fibonacci <- function(n){ x <- rep(1,n) for(i in 3:n){ x[i] <- x[i-1] + x[i-2] } x } fibonacci(15)
|
1
| ## [1] 1 1 2 3 5 8 13 21 34 55 89 144 233 377 610
|
练习
编写一个函数solve.equ, 可以用来解一元二次方程 $ax^2 + bx + c = 0$
- 输入为系数, a,b,c
- 输出为方程的解
- 注意在不同系数条件下, 方程解的不同(只输出实数解)
一元二次方程求解程序
1 2 3 4 5 6 7 8 9 10 11 12
| solve.equ <- function(a,b,c){ if(a == 0){ if(b == 0){ if(c == 0) return("a=b=c=0") else return("No solution!") } else cat("x =", -c/b) } else{ delta <- b^2 - 4*a*c if(delta > 0) cat("x1 =", (-b + sqrt(delta))/(2*a), ", x2 =", (-b - sqrt(delta))/(2*a)) else{ if(abs(delta - 0) < 10^(-5)) cat("x =", -b/2/a) else return("No real solution!") } } }
|