【R语言笔记 (2/4)】Coursera_R Programming

6 Control structure oin R

6.1 Introduction

  • if, else: 测试逻辑条件;
  • for: 执行固定次数的循环;
  • while: 执行条件为真时的循环;
  • repeat: 用于执行无限循环结构;
  • break: 终止并结束循环;
  • next: 跳过循环中的迭代;
  • return: 从函数中推出;

6.2 If-Else

  • if-else的不同表达方式
if(<condition>) {
  ## do something
} else {
  ## do something else
}

or
if(<condition>) {
  ## do something
} else if(<condition2>) {
  ## do something different
} else {
  ## do something different
}

or
if(<condition>) {
  ## do something
}
if(<condition2) {
  ## do somthing different
}
  • 举例
if(x>3) {
  y<-10
} else {
  y<-0
}

y<-if(x>3) {
  10
} else {
  0
}

6.3 For loops

  • for循环的不同表达方式
x<-c("a","b","c","d")

for (i in 1:4) {
  print(x[i])
}

for (i in seq_along(x)) {
  print(x[i])
} ## seq_along是基于x的长度生成的序列

for (letter in x) {
  print(letter)
}

for (i in 1:4) print(x[i])
  • for循环在矩阵的中通常需要先进行行(列)循环再进行列(行)循环
x<-matrix(1:6,2,3)

for (i in seq_len(nrow(x))) {
  for (j in seq_len(ncol(x))) {
    print(x[i,j])
  }
}

- 当for循环中嵌套的层数大于3/4层时代码可读性可能会变得很低;

6.4 While loops

  • 举例
## one condition
count<-0
while (count<10) {
  print(count)
  count<-count+1
}

## more than one condition
z<-5
while (z>=3 && z<=10) {
  print(z)
  coin<-rbinom(1,1,0.5)
  
  if(coin==1) { ## random walk生成随机数,这里循环什么时候结束是不确定的
    z<-z+1
  } else {
      z<-z-1
    }
}

- while循环需要设置终止程序,否则会无限运行下去;
- while循环有多个条件时,系统总是从左向右检验;

6.5 Repeat, Next, Break

  • repeat, break: repeat是一个无限循环结构,退出的方法是break(在某个点强制退出)。比如:当你想计算两个值何时达到无限接近,需要通过算法不断循环,直到逼近你设置的容差
x0<-1
to1<-1e-8

repeat {
  x1<-computeEstimate() 
  ## computeEstimate() is not a real function,需要事先设定
  
  if (abs(x1-x0)<to1) {
    break
  } else {
    x0<-x1
  }
}
  • next, return: next用于跳过某一段循环,return用于跳出函数,并返回一个值,但它同样可以打断循环
for (i in 1:100) {
  if (i<=20) {
    ## Skip the first 20 interations
    next
  }
  ## Do somthing here
}

- 在命令行和交互作用来说有其他的循环函数,如apply()等一系列函数;

7 R function

7.1 First R function

  • 函数举例
## 两数字相加
add2<-function(x,y) {
  x+y
}
add2(3,5)

## 返回列表中大于10的数
above10<-function(x) {
  use<-x>10
  x[use]
}

above<-function(x,n = 10) {
  use<-x>n
  x[use]
}

## 求每一列均值
columnmean<-function(y, removeNA = TRUE) { ## 去除所有空值
  nc<-ncol(y)
  means<-numeric(nc)
  for (i in 1:nc) {
    means[i]<-mean(y[,i], na.rm = removeNA)
  }
  means
}

7.2 Functions

  • 创建函数:用function()函数进行创建,以R对象的形式进行存储,可以理解为function为程序内的一级函数,由function定义的函数为嵌套函数
f<-function(<arguments>) (
  ## Do something intersting
)
  • 参数:定义参数时通常会设置一个默认值,当该参数可以为缺失值时则不用设置
> mydata <- rnorm(100)
> sd(mydata)
[1] 0.9194398
> sd(x = mydata)
[1] 0.9194398
> sd(x = mydata, na.rm = FALSE)
[1] 0.9194398
> sd(na.rm = FALSE, x = mydata)
[1] 0.9194398
> sd(na.rm = FALSE, mydata)
[1] 0.9194398

- na.rm表示是否剔除缺失值,当为TRUE时表示保留缺失值,反之表示剔除缺失值;
- 当参数较多时,参数顺序可以调换;
- 当参数命名过长时,可以输入参数的部分,只要那个部分有唯一的匹配,R就可以进行模糊匹配;

  • Lazy evaluation 惰性求值:函数不会调用所有的参数,只会调用需要的参数,当需要的参数缺失时,系统报错
> f <- function(a, b) {
+   print(a)
+ }
> f(45)
[1] 45

> f <- function(a, b) {
+   print(a)
+   print(b)
+ }
> f(45)
[1] 45
Error in print(b) : argument "b" is missing, with no default
  • "…“参数:表明一些可以传递给另一个函数的参数
    1.当打算拓展一个函数(对一个已经完善的函数进行小部分的更改),但又不想重新把参数复制一遍时,可以使用”…“进行省略;
    2.用于generic functions 泛化函数,这种函数通常不做任何事,它的作用是根据数据类型使用合适的方法,这类函数设置时通常需要用到…参数;
    3.”…“也可以用来跳过前面一些无法事先确定但必须的参数;
    4.出现在”…"后的参数必须明确地给出名称,且不能进行部分匹配;
## eg1
myplot <- function(x, y, type = "l", ...) {
  plot(x, y, type = type, ...)
}

## eg2
> mean
function (x, ...) 
UseMethod("mean")

## eg3
> args(paste)
function (..., sep = " ", collapse = NULL, recycle0 = FALSE) 

## eg4
> paste("a", "b", sep = ":")
[1] "a:b"
> paste("a","b",se = ":")
[1] "a b :" ## 此时无法对a, b进行连接

8 Scoping rules

8.1 Symbol binding

  • 向量和函数同名时并不冲突,由环境决定调用对象:
> search()
 [1] ".GlobalEnv"        "tools:rstudio"    
 [3] "package:stats"     "package:graphics" 
 [5] "package:grDevices" "package:utils"    
 [7] "package:datasets"  "package:methods"  
 [9] "Autoloads"         "package:base"    
  • 环境的定义:
    1.符号或值对的集合,可以把R中所有的东西都想成成对的符号和值;
    2.每一个环境都有一个父环境(parent environment),可能有多个子环境(children);
    3.只有一个环境没有父环境,这个环境为空;
    4.function + an environment = a closure or function closure (闭包)

8.2 Lexical scoping

  • 查找自由变量:
    函数定义的环境 -> 父环境 -> 全局环境 -> 空环境 -> 报错
  • 作用域的意义:
    R与其他语言的一个区别在于 可以在函数中定义函数,其他语言如C是无法做到的,这是定义这个函数的环境是另一个函数,而非全局环境。
  • 构造函数:在函数中构造另一个函数
> make.power <- function(n) {
+   pow <- function(x) {
+     x^n
+   }
+   pow
+ }
> cube <- make.power(3) ## cube函数的环境中n=3
> square <- make.power(2) ## square函数的环境中n=2
> cube(3)
[1] 27
> square(3)
[1] 9

8.3 Lexical vs. Dynamic scoping

  • 词法作用域和动态作用域区别:在f(x)中,y和g(x)均为自由变量,g(x)并非定义在f(x)中,也不是f(x)的参数。而在g(x)中y是一个自由变量。
> y <- 10
> 
> f <- function(x) {
+   y <- 2
+   y^2 + g(x)
+ }
> 
> g <- function(x) {
+   x*y
+ }
> f(3)
[1] 34
  • 词法作用域和动态作用域共性:在全局变量中定义函数并调用函数时,定义环境(defining environment)和调用环境(calling environment)是一致的
> g <- function(x) {
+   a <- 3
+   x+a+y
+ }
> g(2)
Error in g(2) : object 'y' not found
> y <- 3
> g(2)
[1] 8
  • 据说计算机编程语言的尽头是Lisp。

8.4 Application: Optimization

R中处理优化问题的一个基本思想是,你可以利用构造函数构造一个目标函数,把目标函数定义所依赖的数据及其他包含在目标函数定义的环境中,像打包一样整合起来。
eg. 构造一个负的似然函数:返回正态分布的对数似然函数

make.NegLogLik <- function(data, fixed = c(FALSE, FALSE)) {
  param <- fixed
  function(p) {
    param[!fixed] <- p ## 这里p是想要的参数
    mu <- param[1]
    sigma <- param[2]
    a <- -0.5*length(data)*log(2*pi*sigma^2)
    b <- -0.5*sum((data-mu)^2 / (sigma^2))
    -(a + b)
  }
}

Maximizing a normal likelihood

> set.seed(1); normals <- rnorm(100, 1, 2)
> nLL <- make.NegLogLik(normals)
> nLL
function(p) {
    param[!fixed] <- p
    mu <- param[1]
    sigma <- param[2]
    a <- -0.5*length(data)*log(2*pi*sigma^2)
    b <- -0.5*sum((data-mu)^2 / (sigma^2))
    -(a + b)
  }
<bytecode: 0x0000025f6f8c0a08>
<environment: 0x0000025f73acd2d0>
> ls(environment(nLL))
[1] "data"  "fixed" "param"
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

EcrayyarcE

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值