数学建模社区-数学中国

标题: 《R语言入门与实践》第十章:向量化编程 [打印本页]

作者: 1047521767    时间: 2021-11-24 19:54
标题: 《R语言入门与实践》第十章:向量化编程
         《R语言入门与实践》第十章:向量化编程
% j4 E% ]! R& d0 I6 X+ z. t前言

利用 R 的三大法宝:

来达到编写高效的代码的目的.
! t2 x  T1 }$ k, T这样的代码的特点是可以接受整个向量作为输入,并同时处理向量中的元素.4 ?& g7 E& T7 T# s' c: F
通过以下几个案例来阐述向量化编程

预备知识rep() 函数

格式: rep(c(-1, 1), 5000000)
( m; ?/ H) l+ y0 M功能:接受某个值/向量以及次数,返回该值/向量的重复执行次数长度的更长的向量

system.time() 函数

格式: system.time(function(object))
9 C- m2 Q5 l, u- ]/ ?功能:输入一个语句,返回执行该语句所耗费的时间.

向量化代码向量化代码的定义

可以接受一个含有多个值的向量作为输入,并且同时操作向量中的每一个元素

如何编写向量化代码

原则:

方法一:使用向量化的函数/查找表

程序①——未经向量化

change_symbols <- function(vec){/ M7 T- D5 o+ B! J1 Z: @
for(i in 1:length(vec)){  s4 d6 {, q) j4 y2 ^' ^
if(vec == "DD"){
# Z( n+ Z# F" L) v' y% ^) bvec <- "joker"4 X1 s$ F  X! X
}else if(vec == "C"){
/ f  S% q' {8 v7 L& r; A8 Ovec <- "ace"
1 J, m: `3 @  H1 f" D6 E}else if(vec == "7"){! G, w4 Y. F! B' m4 l4 T9 J
vec <- "king"
! r4 ~, j0 h, X& t}else if(vec == "B"){
7 G6 [5 T; |$ p& avec <- "queen"
1 f1 |5 ^! c8 S- k1 B}else if(vec == "BB"){- l5 G4 W5 _3 s2 Z- c$ N& W6 a
vec <- "jack"& S( b  H- z: z6 `1 W( Z9 }9 o
}else if(vec == "BBB"){7 I! I% t" B+ i9 E7 u+ s% x5 a
vec <- "ten"
+ n! a5 }8 `9 c}else{7 @9 a  ]! v: z1 L: S& w& v- p
vec <- "nine"0 e' h6 E# v9 I3 N6 @
}
5 |; T' [' t: i) z. G* R2 E}& A. B5 `+ o3 [/ q, T8 m2 Z) y
vec1 T0 ~5 U  g, w5 A( o
}

程序②——向量化

change_vec <- function(vec){
5 J" H; m' S* _+ M, oprob <- c("DD" = "joker", "C" = "ace"...)
6 W3 H* m- u$ X. ~unname(prob[vec])
5 _6 _7 n* _7 ~  @* U- y}

6 F* R) G# A2 ^, a+ f
方法二:逻辑值取子集

目的:一次性完成对一类情况中的所有元素的操作# N6 ^1 I% K" v
案例:! h7 i, |& D9 M8 B- P$ }
程序①——未经向量化

abs_loop <- function(vec){. Z# I! v, M% }* `0 v; z1 q/ }
for(i in 1:length(vec)){
! c9 j2 l$ J+ Z" oif(vec < 0){
' c# A% u  W% x6 b" jvec <- -vec" N2 y; U7 o6 ^9 V0 }( h) s$ o
}
7 f  g0 [4 P  d; _2 {}% }) A$ N- I$ @# ]- g* o) D% u0 S
vec* \& @+ W% U0 w+ K0 s6 N
}

程序②——向量化

abs_set <- function(vec){
5 ]! W- n9 z# tnegs <- vec < 01 B. A, j- Z) @- L: N
vec[negs] <- vec[negs] * -1
5 d. Q$ B6 _' R  _# [/ Cvec# J, Y' B+ ?$ E) {
}

未向量化的程序:/ ^9 V5 u2 x3 M3 ?/ Q
if 语句一次只能针对一个元素进行判断,来判断出 vec 中为负数的元素2 U2 V3 v* S  @$ }9 i6 \5 e- y
向量化的程序:
% O4 O- B( Z6 n" T5 u其中, vec < 0 为逻辑测试,返回一个包含 TRUE, FALSE 逻辑值的向量 negs, 通过逻辑值取子集的方法,得到 vec 中为负数的元素, 即 vec[negs].

如何在 R 中编写出快速的 for 循环原则:
  • 能放在循环外的代码,就一定不要放在循环内
  • 确保用来储存循环输出结果的对象必须具备足够的容量,以容纳循环的结果; o$ g" H8 P6 c
范例:一个循环 1000000 次并赋值的 for 循环

在 for 循环之前,定义好一个含有 1000000 个 NA 值的向量.
9 @9 R; R0 @  }7 \' J- d: l在 for 循环之中, 对于对一个向量中的元素进行相应的操作.

% d4 x, [( {# ?& G+ M) X

4 L0 X6 u$ y( E: |: k4 J. C( K5 H# A8 p





欢迎光临 数学建模社区-数学中国 (http://www.madio.net/) Powered by Discuz! X2.5