文章目錄
  1. 1. 内容提要
  2. 2. 选择结构
    1. 2.1. if
    2. 2.2. if和else
    3. 2.3. if和else中需要注意的事项
    4. 2.4. ifelse
    5. 2.5. 多个分支: switch
  3. 3. 循环
    1. 3.1. while
    2. 3.2. repeat
    3. 3.3. for
    4. 3.4. 练习
  4. 4. 函数
  5. 5. 数学函数
  6. 6. 统计函数
  7. 7. 概率函数
    1. 7.1. 概率分布缩写
    2. 7.2. 密度函数
    3. 7.3. 分布函数
    4. 7.4. 练习
    5. 7.5. 分位数函数
    6. 7.6. 生成随机数
    7. 7.7. Reproducible Research
    8. 7.8. 验证分布数字特征
  8. 8. 字符处理函数
    1. 8.1. nchar
    2. 8.2. substr
    3. 8.3. grep
    4. 8.4. sub和gsub
    5. 8.5. strsplit
    6. 8.6. paste
    7. 8.7. 大小写转换
    8. 8.8. 自定义函数
    9. 8.9. 自定义函数举例
    10. 8.10. 函数的嵌套定义
    11. 8.11. 练习
    12. 8.12. 练习
    13. 8.13. 练习
    14. 8.14. 一元二次方程求解程序

内容提要

  1. 控制流
    • 选择结构
    • 循环
  2. 函数
    • 内置函数
    • 包函数
    • 自定义函数

选择结构

if

使用方法: 如果cond为真, 则执行statement

if (cond) statement

1
2
x <- 10
if(x %% 2 == 0) print("Even")
1
## [1] "Even"

if和else

使用方法: 如果cond为真, 则执行statement1, 否则执行statement2

if (cond) statement1 else statement2

1
2
x <- 9
if(x %% 2 == 0) print("Even") else print("Odd")
1
## [1] "Odd"

if和else中需要注意的事项

  1. cond条件只能是长度为1的向量
  2. 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
  • repeat
  • for

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
1
## [1] 55

练习

  1. 生成斐波那契数列的前10项
  2. 生成斐波那契数列的所有不超过1000000的项
  3. 生成前1000个质数
  4. 找出最大数不超过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
abs(-4:3)
1
## [1] 4 3 2 1 0 1 2 3
1
sqrt(1:4)
1
## [1] 1.000000 1.414214 1.732051 2.000000
1
ceiling(3.475)
1
## [1] 4
1
floor(3.475)
1
## [1] 3
1
c(trunc(5.99), trunc(-0.9)) ## towards 0
1
## [1] 5 0
1
round(3.475, digits = 2)
1
## [1] 3.48
1
signif(3.475, digits = 2)
1
## [1] 3.5
1
cos(pi/3)
1
## [1] 0.5
1
sin(pi/6)
1
## [1] 0.5
1
tan(pi/4)
1
## [1] 1
1
c(acos(0.5),pi/3)
1
## [1] 1.047198 1.047198
1
c(asin(0.5),pi/6)
1
## [1] 0.5235988 0.5235988
1
c(atan(1),pi/4)
1
## [1] 0.7853982 0.7853982
1
log(exp(2))
1
## [1] 2
1
log10(1000)
1
## [1] 3
1
log(125, base = 5)
1
## [1] 3

统计函数

  • mean, median, quantile
  • sd, var
  • sum, diff
  • min, max, range
  • scale

统计函数示例

1
mean(1:9)
1
## [1] 5
1
mean(c(1:9, NA), na.rm = T)
1
## [1] 5
1
median(1:4)
1
## [1] 2.5
1
quantile(1:100)
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
sd(1:10)
1
## [1] 3.02765
1
var(1:10)
1
## [1] 9.166667
1
sum(1:100)
1
## [1] 5050
1
diff(c(1,5,12,28), lag = 1)
1
## [1]  4  7 16
1
min(10:20)
1
## [1] 10
1
max(10:20)
1
## [1] 20
1
range(10:20)
1
## [1] 10 20
1
scale(1:10)
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 = 生成随机数

概率分布缩写

df1

df2

密度函数

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
pnorm(1.96)
1
## [1] 0.9750021
1
pnorm(1.645)
1
## [1] 0.9500151
1
qnorm(0.975)
1
## [1] 1.959964
1
qnorm(0.95)
1
## [1] 1.644854

生成随机数

1
x <- rnorm(100); mean(x); hist(x)
1
## [1] -0.1276272

Reproducible Research

1
x <- rnorm(100);head(x)
1
## [1] -0.3628155  0.4724650  0.6511996  0.5244914 -1.0902893  0.4615401
1
x <- rnorm(100);head(x)
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
## [1] 20.04
1
2
y <- runif(100, min = 0, max = 1)
mean(y)
1
## [1] 0.5142249

字符处理函数

  • nchar
  • substr
  • grep
  • sub
  • strsplit
  • paste
  • toupper, tolower

nchar

计算字符串长度

1
2
x <- c("ab","cde","fghij")
length(x)
1
## [1] 3
1
nchar(x)
1
## [1] 2 3 5

substr

提取或替换一个字符向量中的子串

1
2
x <- "abcdef"
substr(x,2,4)
1
## [1] "bcd"
1
2
substr(x,2,4) <- "22222"
x
1
## [1] "a222ef"

grep

搜索子串, 可以使用正则表达式

1
2
txt <- c("arm","foot","lefroo", "bafoobar")
grep("foo", txt)
1
## [1] 2 4
1
txt[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      "
1
gsub(" ", "", str)
1
## [1] "Nowisthetime"

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
## [1] "x1" "x2" "x3"
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)
1
## [1] "MIXED CASE 123"
1
tolower(x)
1
## [1] "mixed case 123"

自定义函数

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
## [1] 5
1
hypotenuse(5,12)
1
## [1] 13

函数的嵌套定义

1
2
3
4
5
6
7
8
9
f <- function(x){
y <- 1
g <- function(x){
(x + y)/2
}
g(x)
}

f(3)
1
## [1] 2

练习

输入一个正整数n(n > 3), 输出斐波那契数列的前n项

1
fibonacci(15)
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
solve.equ(1,2,1)
1
## x = -1
1
solve.equ(1,2,0)
1
## x1 = 0 , x2 = -2

一元二次方程求解程序

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!")
}
}
}
文章目錄
  1. 1. 内容提要
  2. 2. 选择结构
    1. 2.1. if
    2. 2.2. if和else
    3. 2.3. if和else中需要注意的事项
    4. 2.4. ifelse
    5. 2.5. 多个分支: switch
  3. 3. 循环
    1. 3.1. while
    2. 3.2. repeat
    3. 3.3. for
    4. 3.4. 练习
  4. 4. 函数
  5. 5. 数学函数
  6. 6. 统计函数
  7. 7. 概率函数
    1. 7.1. 概率分布缩写
    2. 7.2. 密度函数
    3. 7.3. 分布函数
    4. 7.4. 练习
    5. 7.5. 分位数函数
    6. 7.6. 生成随机数
    7. 7.7. Reproducible Research
    8. 7.8. 验证分布数字特征
  8. 8. 字符处理函数
    1. 8.1. nchar
    2. 8.2. substr
    3. 8.3. grep
    4. 8.4. sub和gsub
    5. 8.5. strsplit
    6. 8.6. paste
    7. 8.7. 大小写转换
    8. 8.8. 自定义函数
    9. 8.9. 自定义函数举例
    10. 8.10. 函数的嵌套定义
    11. 8.11. 练习
    12. 8.12. 练习
    13. 8.13. 练习
    14. 8.14. 一元二次方程求解程序