添加链接
link管理
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接
  • 52.2.1 evalCpp() 转换单一计算表达式
  • 52.2.2 cppFunction() 转换简单的C++函数—Fibnacci例子
  • 52.2.3 sourceCpp() 转换C++程序—正负交替迭代例子
  • 52.2.4 sourceCpp() 转换C++源文件中的程序—正负交替迭代例子
  • 52.2.5 sourceCpp() 转换C++源程序文件—卷积例子
  • 52.2.6 随机数例子
  • 52.2.7 bootstrap例子
  • 52.2.8 在Rmd文件中使用C++源程序文件
  • 53 R与C++的类型转换
  • 53.1 wrap() 把C++变量返回到R中
  • 53.2 as() 函数把R变量转换为C++类型
  • 53.3 as() wrap() 的隐含调用
  • 54 Rcpp 属性
  • 54.1 Rcpp属性介绍
  • 54.2 在C++源程序中指定要导出的C++函数
  • 54.2.1 特殊注释 //[[Rcpp::export]]
  • 54.2.2 修改导出的函数名
  • 54.2.3 可导出的函数
  • 54.3 在R中编译链接C++代码
  • 54.3.1 sourceCpp() 函数中直接包含C++源程序字符串
  • 54.3.2 cppFunction() 函数中直接包含C++函数源程序字符串
  • 54.3.3 evalCpp() 函数中直接包含C++源程序表达式字符串
  • 54.3.4 depends 指定要链接的库
  • 54.4 Rcpp属性的其它功能
  • 54.4.1 自变量有缺省值的函数
  • 54.4.2 异常传递
  • 54.4.3 允许用户中断
  • 54.4.4 把R代码写在C++源文件中
  • 54.4.5 invisible 要求函数结果不自动显示
  • 54.4.6 在C++中调用R的随机数发生器
  • 55 Rcpp提供的C++数据类型
  • 55.1 RObject类
  • 55.2 IntegerVector类
  • 55.2.1 IntegerVector示例1:返回完全数
  • 55.2.2 IntegerVector示例2:输入整数向量
  • 55.3 NumericVector类
  • 55.3.1 示例1:计算元素 \(p\) 次方的和
  • 55.3.2 示例2: clone 函数
  • 55.3.3 示例3:向量子集
  • 55.4 NumericMatrix类
  • 55.4.1 示例1:计算矩阵各列模的最大值
  • 55.4.2 示例2:把输入矩阵制作副本计算元素平方根
  • 55.4.3 示例3:访问列子集
  • 55.5 Rcpp的其它向量类
  • 55.5.1 Rcpp的LogicalVector类
  • 55.5.2 Rcpp的CharacterVector类型
  • 55.6 Rcpp提供的其它数据类型
  • 55.6.1 Named类型
  • 55.6.2 List类型
  • 55.6.3 Rcpp的DataFrame类
  • 55.6.4 Rcpp的Function类
  • 55.6.5 Rcpp的Environment类
  • 56 Rcpp糖
  • 56.1 简单示例
  • 56.2 向量化的运算符
  • 56.2.1 向量化的四则运算
  • 56.2.2 向量化的赋值运算
  • 56.2.3 向量化的二元逻辑运算
  • 56.2.4 向量化的一元运算符
  • 56.3 用Rcpp访问数学函数
  • 56.4 用Rcpp访问统计分布类函数
  • 56.5 在Rcpp中产生随机数
  • 56.6 返回单一逻辑值的函数
  • 56.7 返回糖表达式的函数
  • 56.7.1 is_na
  • 56.7.2 seq_along
  • 56.7.3 seq_len
  • 56.7.4 pmin pmax
  • 56.7.5 ifelse
  • 56.7.6 sapply lapply
  • 56.7.7 sign
  • 56.7.8 diff
  • 56.8 R与Rcpp不同语法示例
  • 56.9 用RcppArmadillo执行矩阵运算
  • 56.9.1 生成多元正态分布随机数
  • 56.9.2 快速计算线性回归
  • 57 用Rcpp帮助制作R扩展包
  • 57.1 不用扩展包共享C++代码的方法
  • 57.2 生成扩展包
  • 57.2.1 利用已有基于Rcpp属性的源程序制作扩展包
  • 57.2.2 DESCRIPTION文件
  • 57.2.3 NAMESPACE文件
  • 57.3 重新编译
  • 57.4 建立C++用的接口界面
  • XI 其它
  • 58 R编程例子
  • 58.1 R语言
  • 58.1.1 用向量作逆变换
  • 58.1.2 斐波那契数列计算
  • 58.1.3 穷举所有排列
  • 58.1.4 可重复分组方式穷举
  • 58.1.5 升降连计数
  • 58.1.6 高斯八皇后问题
  • 58.1.7 最小能量路径
  • 58.2 概率
  • 58.2.1 智者千虑必有一失
  • 58.2.2 圆桌夫妇座位问题
  • 58.3 科学计算
  • 58.3.1 城市间最短路径
  • 58.3.2 Daubechies小波函数计算
  • 58.3.3 房间加热温度变化
  • 58.4 统计计算
  • 58.4.1 线性回归实例
  • 58.4.2 核回归与核密度估计
  • 58.4.3 二维随机模拟积分
  • 58.4.4 潜周期估计
  • 58.4.5 ARMA(1,1)模型估计
  • 58.4.6 VAR模型平稳性
  • 58.4.7 贮存可靠性评估
  • 58.5 数据处理
  • 58.5.1 小题分题型分数汇总
  • 58.5.2 类别编号重排
  • 58.6 文本处理
  • 58.6.1 用R语言下载处理《红楼梦》htm文件
  • 59 使用经验
  • 59.1 文件管理
  • 59.1.1 工作空间
  • 59.2 程序格式
  • A R Markdown文件格式
  • A.1 R Markdown文件
  • A.2 R Markdown文件的编译
  • A.2.1 编译的实际过程
  • A.3 在R Markdown文件中插入R代码
  • A.4 输出表格
  • A.5 利用R程序插图
  • A.6 冗余输出控制
  • A.7 代码段选项
  • A.7.1 代码和文本输出结果格式
  • A.7.2 图形选项
  • A.7.3 缓存(cache)选项
  • A.8 章节目录链接问题
  • A.9 其它编程语言引擎
  • A.10 交互内容
  • A.11 属性设置
  • A.11.1 YAML元数据
  • A.11.2 输出格式
  • A.11.3 输出格式设置
  • A.11.4 目录设置
  • A.11.5 章节自动编号
  • A.11.6 Word输出章节自动编号及模板功能
  • A.11.7 HTML特有输出格式设置
  • A.11.8 关于数学公式支持的设置
  • A.11.9 输出设置文件
  • A.12 LaTeX和PDF输出
  • A.12.1 TinyTex的安装使用
  • A.12.2 Rmd中Latex设置
  • A.13 生成期刊文章
  • A.14 附录:经验与问题
  • A.14.1 Word模板制作
  • A.14.2 数学公式设置补充
  • B 用bookdown制作图书
  • B.1 介绍
  • B.2 一本书的设置
  • B.3 章节结构
  • B.4 书的编译
  • B.5 交叉引用
  • B.6 数学公式和公式编号
  • B.7 定理类编号
  • B.8 文献引用
  • B.9 插图
  • B.10 表格
  • B.10.1 Markdown表格
  • B.10.2 kable() 函数制作表格
  • B.10.3 R中其它制作表格的包
  • B.11 数学公式的设置
  • B.12 使用经验
  • B.12.1 学位论文
  • B.12.2 LaTeX
  • B.12.3 算法
  • B.12.4 中文乱码
  • B.12.5 图片格式
  • B.12.6 其它经验
  • B.13 bookdown的一些使用问题
  • C 用R Markdown制作简易网站
  • C.1 介绍
  • C.2 简易网站制作
  • C.2.1 网站结构
  • C.2.2 编译
  • C.2.3 内容文件
  • C.2.4 网站设置
  • C.3 用blogdown制作网站
  • C.3.1 生成新网站的框架
  • C.3.2 网页内容文件及其设置
  • C.3.3 初学者的工作流程
  • C.3.4 网站设置文件
  • C.3.5 静态文件
  • D 制作幻灯片
  • D.1 介绍
  • D.2 Slidy幻灯片
  • D.2.1 文件格式
  • D.2.2 幻灯片编译
  • D.2.3 播放控制
  • D.2.4 生成单页HTML
  • D.2.5 数学公式处理与输出设置文件
  • D.2.6 其它选项
  • D.2.7 slidy幻灯片激光笔失效问题的修改
  • D.3 MS PowerPoint幻灯片
  • D.4 Bearmer幻灯片格式
  • D.5 R Presentation格式
  • References
  • 编著:李东风
  • y <- ifelse (x >= 0 , 1 , 0 ); print (y)
    ## [1] 0 1 1

    函数 ifelse(test, yes, no) 中的 test 是逻辑向量, yes no 是向量, test yes no 的配合符合向量化原则, 如果有长度为1的或者长度较短但其倍数等于最长一个的长度的, 短的一个自动从头循环使用。如:

    ifelse((1:6) >= 3, 1:2, c(-1,-2))
    ## [1] -1 -2  1  2  1  2

    当然,最常见的还是 yes no 为标量的情形。

    不同于 if 语句, ifelse test 中运行有缺失值, 对应结果也是缺失值。

    dplyr包的 if_else 函数与基本R的 ifelse 功能基本相同, 但允许指定条件为缺失值时的不同处理方法。

    16.2.3 switch 函数

    函数 switch() 可以建立多分枝结构, 可以根据一个整数表达式或者一个字符串表达式的值选择返还相对应的值。

    例如,某校将百分制转换到等级制的规则如下:

  • 98-100: A+
  • 95-97: A
  • 90-94: A-
  • 85-89: B+
  • 80-84: B
  • 77-79: B-
  • 73-76: C+
  • 70-72: C
  • 67-69: C-
  • 63-66: D+
  • 60-62: D
  • 0-59: F
  • 从百分制转换为等级制可以用 if-else if-else 完成。 从等级制转换回百分制,用区间平均值,可以写成 switch() 的写法:

    gr_v <- c("A+", "A", "A-", "B+", "B", "B-", 
      "C+", "C", "C-", "D+", "F", "EX")
    for(gr in gr_v){
      switch(gr,
        "A+" = 99,
        "A" = 96,
        "A-" = 92,
        "B+" = 87,
        "B" = 82,
        "B-" = 78,
        "C+" = 75,
        "C" = 71,
        "C-" = 68,
        "D+" = 65,
        "F" = 50,
    

    switch()中的最后一个选择通常用于所有前面选择都不匹配时的一个例外情况处理, 这里的例子对这种情况返回缺失值。 上例中用了for循环,见下一节的说明。

    switch()中允许对多个值采取同一行动或者返回同一结果,

    for(ch in c("a", "i", "c")){
      cat(ch, ":", switch(ch,
        "a"=, "e"=, "i"=, "o"=, "u" = "Vower",
        "Consonant"), "\n")
    
    ## a : Vower 
    ## i : Vower 
    ## c : Consonant

    在上例中,a, e, i, o, u返回相同的值"Vower", 而其它值则返回"Consonant"

    如果要建立\(1:n\)\(x_1 \sim x_n\)的映射, 可以用整数下标的方法; 如果要建立\(s_1 \sim s_n\)(字符串向量)到\(x_1 \sim x_n\)的映射, 可以用有名向量的方法。 switch()则可以处理有例外项的问题。 更一般的分支, 尤其是不同分支执行不同命令的情况, 应该使用if-else if-else结构。

    dplyr包的case_when函数可以switch()的向量化推广, 看成是ifelse的多分支推广, 或看成if-else if-else语句的向量化。 输入条件是向量化的, 根据输入条件返回条件对应的结果。 所有条件都不满足的元素的输出结果为NA`。

    ##  [1] 99 96 92 87 82 78 75 71 68 65 50 NA
    x <- c("a", "i", "c")
    dplyr::case_when(
      x %in% c("a", "e", "i", "o", "u") 
      ~ "Vowel",
      ~ "Consonant"
    
    ## [1] "Vowel"     "Vowel"     "Consonant"

    16.3 循环结构

    16.3.1 计数循环

    为了对向量每个元素、矩阵每行、矩阵每列循环处理,语法为

    for(循环变量 in 序列) 语句

    其中的语句一般是复合语句。

    ## [1] 0 1 0 1 1

    其中rnorm(5)会生成5个标准正态分布随机数。 numeric(n)生成有n个0的数值型向量(基础类型为double)。

    如果需要对某个向量x按照下标循环, 获得所有下标序列的标准写法是seq_along(x), 而不用1:n的写法, 因为在特殊情况下n可能等于零,这会导致错误下标, 而seq_along(x)x长度为零时返回零长度的下标。

    例如,设序列\(x_n\)满足\(x_0=0\), \(x_n = 2 x_{n-1} + 1\), 求\(S_n = \sum_{i=1}^n x_n\):

    x <- 0.0; s <- 0; n <- 5
    for(i in 1:n){
      x <- 2*x + 1
      s <- s + x
    print(s)
    ## [1] 57

    在R中应尽量避免for循环: 其速度比向量化版本慢一个数量级以上, 而且写出的程序不够典雅。 比如,前面那个示性函数例子实际上可以简单地写成

    ## [1] 0 1 0 1 1

    许多计数循环都可以用lapplyvapplysapplyapplymapMap等函数替代, 详见18.3

    break语句退出所在的循环。 用next语句进入所在循环的下一轮。

    使用for循环的注意事项:

  • 如果对向量每个元素遍历并保存结果, 应在循环之前先将结果变量产生等长的存储, 在循环内为已经分配好存储空间的输出向量的元素赋值。 为了产生长度为n的数值型向量,用numeric(n); 为了产生长度为n的列表,用vector("list", n)
  • 对一个向量元素遍历时如果用下标访问, 需要用seq_along(x)的做法而不是1:length(x)的做法。
  • 如果直接对向量元素遍历, 这有可能会丢失向量的属性(如日期型), 用下标访问则不存在此问题。
  • ## [1] 360086400
    ## [1] 1582300800
    ## [1] "1981-05-31 CST"
    ## [1] "2020-02-22 CST"

    16.3.2 while循环和repeat循环

    while(循环继续条件) 语句

    进行当型循环。 其中的语句一般是复合语句。 仅当条件成立时才继续循环, 而且如果第一次条件就已经不成立就一次也不执行循环内的语句。

    repeat 语句

    进行无条件循环(一般在循环体内用if与break退出)。 其中的语句一般是复合语句。 如下的写法可以制作一个直到型循环:

    repeat{
      if(循环退出条件) break
    

    直到型循环至少执行一次, 每次先执行...代表的循环体语句, 然后判断是否满足循环退出条件, 满足条件就退出循环。

    常量\(e\)的值可以用泰勒展开式表示为 e = 1 + \sum_{k=1}^\infty \frac{1}{k!} R函数exp(1)可以计算e的为了计算\(e\)的值, 下面用泰勒展开逼近计算e的值:

    ## k= 18  s= 2.718282  e= 2.718282  误差= 4.440892e-16

    其中.Machine$double.eps称为机器\(\varepsilon\), 是最小的加1之后可以使得结果大于1的正双精度数, 小于此数的正双精度数加1结果还等于1。 用泰勒展开公式计算的结果与exp(1)得到的结果误差在\(10^{-16}\)左右。

    16.4 R中判断条件

    if语句和while语句中用到条件。 条件必须是标量值, 而且必须为TRUE或FALSE, 不能为NA或零长度。 这是R编程时比较容易出错的地方。

    16.5 管道控制

    数据处理中经常会对同一个变量(特别是数据框)进行多个步骤的操作, 比如,先筛选部分有用的变量,再定义若干新变量,再排序。 R从4.1.0版本开始提供了一个|>运算符实现这样的操作流程, R的magrittr包提供了一个%>%运算符执行类似功能。 比如,变量x先用函数f(x)进行变换,再用函数g(x)进行变换, 一般应该写成g(f(x)),用|>运算符,可以表示成 x |> f() |> g()。 更多的处理,如h(g(f(x)))可以写成 x |> f() |> g() |> h()。 这样的表达更符合处理发生的次序,而且插入一个处理步骤也很容易。

    处理用的函数也可以带有其它自变量,在管道控制中不要写第一个自变量。

    ## [1] 4.11325

    结果为\(e^{\sqrt{2}}\)

    ## [1] 0.5236

    这等价于round(asin(0.5), digits=4)

    |>表示的管道中, 上一步的输出通过管道作为下一步的第一个自变量。 如果需要当作下一步的其它自变量, 可以用自变量名 = _的特殊格式, 这里_代表管道中上一步的结果。如:

    ## [1] 3.141593

    这等价于round(pi, digits=6)

    tibble类型的数据框尤其适用于如此的管道操作, 在23中有大量使用管道进行多步骤操作的例子。

    magrittr包定义了%T%运算符, x %T% f()返回x本身而不是用f()修改后的返回值f(x), 这在中间步骤需要显示或者绘图但是需要进一步对输入数据进行处理时有用。

    magrittr包定义了%$%运算符, 此运算符的作用是将左运算元的各个变量(这时左运算元是数据框或列表)暴露出来, 可以直接在右边调用其中的变量,类似于with()函数的作用。

    magrittr包定义了%<>%运算符, 用在管道链的第一个连接, 可以将处理结果存入最开始的变量中, 类似于C语言的+=运算符。

    如果一个操作是给变量加b,可以写成add(b), 给变量乘b,可以写成multiply_by(b)