数学建模社区-数学中国

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

作者: 1047521767    时间: 2021-11-24 19:54
标题: 《R语言入门与实践》第十章:向量化编程
         《R语言入门与实践》第十章:向量化编程
1 e$ u1 F9 V. G% ~3 i- |前言

利用 R 的三大法宝:

来达到编写高效的代码的目的.0 q) _) n' K' v; x
这样的代码的特点是可以接受整个向量作为输入,并同时处理向量中的元素.$ e  u. R4 v1 q1 z- a  c
通过以下几个案例来阐述向量化编程

预备知识rep() 函数

格式: rep(c(-1, 1), 5000000)# _% Q: c0 D4 e0 K& y- F5 y& W; X( B
功能:接受某个值/向量以及次数,返回该值/向量的重复执行次数长度的更长的向量

system.time() 函数

格式: system.time(function(object))
! L- I2 ]4 w: U" B/ k& S' @/ ]功能:输入一个语句,返回执行该语句所耗费的时间.

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

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

如何编写向量化代码

原则:

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

程序①——未经向量化

change_symbols <- function(vec){) b1 a9 i# R! X. Q' V, W
for(i in 1:length(vec)){
) o4 h0 U% C( `2 vif(vec == "DD"){7 t+ a; e( W) o! z3 x5 A
vec <- "joker"
, y" l$ e: x1 Q2 P}else if(vec == "C"){
* g8 X. ]. l# Avec <- "ace"
% s$ \6 `8 \# l' V}else if(vec == "7"){4 r; Y% ]9 a% F' j: w" m1 Z
vec <- "king"
! s" V2 [/ h# t}else if(vec == "B"){
) b. h9 M" R; q6 i6 Xvec <- "queen"+ V# H& E9 n2 x
}else if(vec == "BB"){
7 }# ~2 |& I0 E) p8 U; `# a' {vec <- "jack"
- F; `5 W4 `" ?) s! d0 k' d}else if(vec == "BBB"){' i" j6 d' m* H3 O: B0 J& C$ c
vec <- "ten"
5 u3 D! X" R( |9 J3 X4 W5 s5 ^; {}else{
0 A# u1 F" f  w& k  Tvec <- "nine"
. ^7 _$ ?( }- G# O; m}! Z3 E; a4 K+ R- B9 W; [
}1 U* f% }4 R% |2 o" W
vec- s" L. U) B6 D0 H
}

程序②——向量化

change_vec <- function(vec){
( L6 o3 }+ v0 W" u- l$ i  d1 w. _prob <- c("DD" = "joker", "C" = "ace"...)
$ ]" L4 U8 b" V# sunname(prob[vec])% x: W/ {- [+ n
}

8 s% d  y, d5 ]+ `2 Q" B* ]+ q
方法二:逻辑值取子集

目的:一次性完成对一类情况中的所有元素的操作& X- v) Y' i& a7 [/ A
案例:
  a- O" o0 ~4 Q4 r: Q程序①——未经向量化

abs_loop <- function(vec){
+ J1 z5 N$ n1 v9 u* W( n( U1 pfor(i in 1:length(vec)){1 |0 M6 o) ~( f% n
if(vec < 0){
& L6 F, \/ H* v  M* Cvec <- -vec5 @" Q3 L; f2 D; A6 S  o) q
}7 A9 a& j$ b' o: \  N9 B; G' G* C$ L7 ~
}
; o3 V6 Y- a9 f9 a+ H) _; p* E! Svec
  Z: x0 `, ]1 T5 o& R+ O; c}

程序②——向量化

abs_set <- function(vec){
* u' G' ^0 K9 ~8 i: z2 qnegs <- vec < 0
: a, o: f/ D5 R! L( N+ cvec[negs] <- vec[negs] * -12 h8 z6 ]+ ?  K* U
vec+ @# v! i* v( E( Q) f* o7 d
}

未向量化的程序:' m4 H6 t0 J5 y& z, t$ j/ t( J/ U
if 语句一次只能针对一个元素进行判断,来判断出 vec 中为负数的元素; e) v+ i1 j) C) W8 b  H
向量化的程序:
4 [9 k1 }8 h7 U3 P' _其中, vec < 0 为逻辑测试,返回一个包含 TRUE, FALSE 逻辑值的向量 negs, 通过逻辑值取子集的方法,得到 vec 中为负数的元素, 即 vec[negs].

如何在 R 中编写出快速的 for 循环原则:
  • 能放在循环外的代码,就一定不要放在循环内
  • 确保用来储存循环输出结果的对象必须具备足够的容量,以容纳循环的结果
    ! s8 i/ ]0 s$ x) P
范例:一个循环 1000000 次并赋值的 for 循环

在 for 循环之前,定义好一个含有 1000000 个 NA 值的向量.
, K1 |1 F& L( i$ b8 r在 for 循环之中, 对于对一个向量中的元素进行相应的操作.


8 V4 Q, v) y/ h% D7 r7 e3 @4 ?
1 e. n, `; k8 X: @  ^% L$ _  \5 P% n" t+ a* z+ e$ }8 ~





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