QQ登录

只需要一步,快速开始

 注册地址  找回密码
查看: 3831|回复: 0
打印 上一主题 下一主题

《R语言入门与实践》第十章:向量化编程

[复制链接]
字体大小: 正常 放大

1178

主题

15

听众

1万

积分

  • TA的每日心情
    开心
    2023-7-31 10:17
  • 签到天数: 198 天

    [LV.7]常住居民III

    自我介绍
    数学中国浅夏
    跳转到指定楼层
    1#
    发表于 2021-11-24 19:54 |只看该作者 |倒序浏览
    |招呼Ta 关注Ta
             《R语言入门与实践》第十章:向量化编程
    . }/ w" V$ Y% m% E前言

    利用 R 的三大法宝:

    • 逻辑判断
    • 取子集
    • 按元素方式执行% u% @; o9 Z6 E, E- P* A

    来达到编写高效的代码的目的.& G/ W; ?/ b4 d4 n9 _+ X$ u
    这样的代码的特点是可以接受整个向量作为输入,并同时处理向量中的元素.
    : b' E+ g0 E( M$ B* m2 m+ R通过以下几个案例来阐述向量化编程

    预备知识rep() 函数

    格式: rep(c(-1, 1), 5000000)9 f* J4 e4 `/ R4 Q
    功能:接受某个值/向量以及次数,返回该值/向量的重复执行次数长度的更长的向量

    system.time() 函数

    格式: system.time(function(object))* D( h: _9 H( A9 r/ F
    功能:输入一个语句,返回执行该语句所耗费的时间.

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

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

    如何编写向量化代码

    原则:

    • 尽量使用向量化的函数来完成任务:比如使用 R 库中的原函数
    • 对于重复的情况,使用逻辑值取子集的方法,而不是 for & if 的方法.
      $ h2 W7 g  N# t$ y
    方法一:使用向量化的函数/查找表

    程序①——未经向量化

    change_symbols <- function(vec){
    3 W! e2 }. B: `- X3 ^2 f1 gfor(i in 1:length(vec)){, B% h; w" v  g3 a" @' U% O
    if(vec == "DD"){
    3 E9 j1 Q& k; \8 Vvec <- "joker"7 S4 n: d+ A* J) w3 s/ ?% v
    }else if(vec == "C"){
    4 {6 \& R  F& H/ l2 ?  D, h/ Evec <- "ace"
    7 {: n1 ?: L3 I5 [}else if(vec == "7"){0 R8 ]: i8 p$ n% v
    vec <- "king"; V: B. v% A% E) j
    }else if(vec == "B"){7 H  |9 |# n, C6 s
    vec <- "queen"
    ) M) s( {, ^1 R6 V0 T}else if(vec == "BB"){
    $ \# g+ [  Y+ }9 G: ivec <- "jack"
    $ E  S" c+ ~& t+ x}else if(vec == "BBB"){5 e7 t+ R/ t2 f
    vec <- "ten"
    & _- E- w8 d8 e) W4 J6 W}else{' x, r, e8 B$ A# B5 o* U) I
    vec <- "nine"7 ~4 q7 _) s' Y* |& k+ J
    }
    / j  Q/ U' c& l  _; v& Y}8 W+ Z2 L5 T) T; o# g
    vec
    0 ^* ~$ u8 z. h8 M" \* S}

    程序②——向量化

    change_vec <- function(vec){
    % n- A" ^/ }( L2 ]) Fprob <- c("DD" = "joker", "C" = "ace"...)7 H4 `6 `) }+ j2 h6 U
    unname(prob[vec])) d% \  {# A2 X9 _6 U4 k2 \6 M
    }

    0 A' Q6 F8 G- z  ], h
    方法二:逻辑值取子集

    目的:一次性完成对一类情况中的所有元素的操作
    2 c% n$ p4 R6 C" V7 P1 W; [案例:7 ^2 T0 ]3 u2 c; L9 }+ Y5 T9 q
    程序①——未经向量化

    abs_loop <- function(vec){: P& `6 p0 i) L% J0 I. U8 C4 h2 d0 u9 F
    for(i in 1:length(vec)){
    # b& E3 n( h2 Q/ ^( zif(vec < 0){# S) t6 @% W7 B, N
    vec <- -vec
      }# Y: T0 Q+ U3 _}8 [+ V1 D( E- t: H* v) X
    }
    6 g2 o8 S1 _" d5 Z1 ^vec
    ' @- J- i6 ]& q' h}

    程序②——向量化

    abs_set <- function(vec){
    4 Z% [" v- G/ W1 Znegs <- vec < 0* }; y- Q. D! {* a( S. `* R8 n
    vec[negs] <- vec[negs] * -1  L2 X7 j! Z6 n" }' s4 N; }
    vec
    2 |! s- ~/ u) f2 K8 H}

    未向量化的程序:
    7 M( f1 C& r2 t4 P& Bif 语句一次只能针对一个元素进行判断,来判断出 vec 中为负数的元素1 Z) t) I# d0 U: g. D5 h
    向量化的程序:
    . I5 g5 y% q9 Z7 R! @其中, vec < 0 为逻辑测试,返回一个包含 TRUE, FALSE 逻辑值的向量 negs, 通过逻辑值取子集的方法,得到 vec 中为负数的元素, 即 vec[negs].

    如何在 R 中编写出快速的 for 循环原则:
    • 能放在循环外的代码,就一定不要放在循环内
    • 确保用来储存循环输出结果的对象必须具备足够的容量,以容纳循环的结果& H3 [' C. {3 J2 L; a. ?  }, a8 o
    范例:一个循环 1000000 次并赋值的 for 循环

    在 for 循环之前,定义好一个含有 1000000 个 NA 值的向量.
    8 O; f0 y  t1 `: I8 a6 s% _7 E在 for 循环之中, 对于对一个向量中的元素进行相应的操作.


    ' A' L. b4 d$ A7 S, K2 t) f( q$ b  f/ m3 u2 A
    ) u; \9 A* M7 V* H7 R" r
    zan
    转播转播0 分享淘帖0 分享分享0 收藏收藏0 支持支持0 反对反对0 微信微信
    您需要登录后才可以回帖 登录 | 注册地址

    qq
    收缩
    • 电话咨询

    • 04714969085
    fastpost

    关于我们| 联系我们| 诚征英才| 对外合作| 产品服务| QQ

    手机版|Archiver| |繁體中文 手机客户端  

    蒙公网安备 15010502000194号

    Powered by Discuz! X2.5   © 2001-2013 数学建模网-数学中国 ( 蒙ICP备14002410号-3 蒙BBS备-0002号 )     论坛法律顾问:王兆丰

    GMT+8, 2026-5-27 19:10 , Processed in 0.394136 second(s), 50 queries .

    回顶部