美文网首页收藏
91.for循环的其他模式

91.for循环的其他模式

作者: 心惊梦醒 | 来源:发表于2022-01-09 10:58 被阅读0次

        purrr包还提供了其他一些抽象表示for循环的函数,这些函数的使用频率比map()函数少,但还是有必要知道一下,以便遇到相似问题的时候可以有查找问题的方向。

    判定函数

        所谓判定函数(predicate functions),就是返回值是逻辑值的函数。一类for循环函数是基于判定函数工作的,包括:
        1)keep()、discard()、compact(),功能分别是保留或丢弃vector或list满足某种条件(由判定函数决定)的元素、删除vector或list中的所有空元素(即NULL,注意NA、NaN等不是空元素)

    keep(.x, .p, ...)
    discard(.x, .p, ...)
    compact(.x, .p = identity)
    
    .x : vector或list
    .p : 判定函数,仅判定函数返回值为TRUE的元素被keep或discard
    ...:其他传递给.f的参数
    
    > keep(1:10,~.>5)
    [1]  6  7  8  9 10
    > discard(1:10,~.>5)
    [1] 1 2 3 4 5
    > compact(rep(c(1,2,NULL),4))
    [1] 1 2 1 2 1 2 1 2
    

        2)every()、some()、none(),功能分别是list或atomic vector中的每一个元素、一些元素或没有一个元素满足判定条件吗?返回值是长度为1的逻辑向量。

    every(.x, .p, ...)
    some(.x, .p, ...)
    none(.x, .p, ...)
    
    .x : list 或atomic vector
    .p :判定函数
    
    > every(1:10,~.>5)
    [1] FALSE
    > some(1:10,~.>5)
    [1] TRUE
    > none(1:10,~.>5)
    [1] FALSE
    

        3)detect()、detect_index(),功能分别是返回第一个匹配的元素、index。

    detect(.x,  .f,  ...,  .dir = c("forward", "backward"),  .right = NULL,  
    .default = NULL)
    detect_index(.x, .f, ..., .dir = c("forward", "backward"), .right = NULL)
    
    正如所看到的参数,可以设置匹配方向,默认是:forward,即从.x的开始向末尾匹配;
    .right参数被废弃了,用.dir代替
    .default:当没有匹配到结果时,默认返回NULL,可以设置为别的。
    

        4)head_while()、tail_while(),功能分别是找到所有满足判定条件的头和尾。

    head_while(.x, .p, ...)
    tail_while(.x, .p, ...)
    
    > head_while(1:10,~.>5)
    integer(0)
    > tail_while(1:10,~.>5)
    [1]  6  7  8  9 10
    
    
    reduce() 和accumulate()

        reduce()函数用来通过反复应用一个能将双例转化为单例的函数,将复杂列表转换成简单列表。

    reduce(.x, .f, ..., .init, .dir = c("forward", "backward"))
    reduce2(.x, .y, .f, ..., .init)
    
    .x:list或atomic vector
    .f:对reduce(),.f应该是有两个原始输入的函数;对reduce2(),.f应该是有三个原始输入的函数
    .init:不指定时,默认.x[[1]]作为初始值;指定时,使用指定值作为初始值
    .dir:如果.f是类似+、c()等连接型的函数,对方向无要求,否则需指定方向,默认"forward"。
    
    举个例子:
    > x <- 1:3
    > reduce(x,`+`)
    [1] 6
    初始值x[1],即1;最后简化为(1+2)+3=6
    > reduce(x,`+`,.init=2)
    [1] 8
    

        我们可以用merge()函数合并两个数据框。如果有多个数据框同时需要合并,可以用reduce()来自动循环执行merge()。

    > (birthtime <- data.frame(name=c("Zhangs","Lis","Wangw","Qianl"),birthtime=c("19900103","19900630","19891203","19920709")))
        name birthtime
    1 Zhangs  19900103
    2    Lis  19900630
    3  Wangw  19891203
    4  Qianl  19920709
    > (sex <- data.frame(name=c("Zhangs","Qianl","Wangw"),sex=c("male","female","male")))
        name    sex
    1 Zhangs   male
    2  Qianl female
    3  Wangw   male
    > (height<-data.frame(name=c("Qianl","Wangw","Lis"),height=c(162,178,158)))
       name height
    1 Qianl    162
    2 Wangw    178
    3   Lis    158
    > reduce(list(birthtime,sex,height),merge,by="name",all=T)
        name birthtime    sex height
    1    Lis  19900630   <NA>    158
    2  Qianl  19920709 female    162
    3  Wangw  19891203   male    178
    4 Zhangs  19900103   male     NA
    
    相当于:
    > (tmp1<-merge(birthtime,sex,by="name",all=T))
    > merge(tmp1,height,by="name",all=T)
    

        accumulate()会保留reduce()每次循环的结果:

    accumulate(.x, .f, ..., .init, .dir = c("forward", "backward"))
    accumulate2(.x, .y, .f, ..., .init)
    
    > accumulate(list(birthtime,sex,height),merge,by="name",all=T)
    # 初始值是birthtime
    [[1]]
        name birthtime
    1 Zhangs  19900103
    2    Lis  19900630
    3  Wangw  19891203
    4  Qianl  19920709
    # 合并birthtime和sex
    [[2]]
        name birthtime    sex
    1    Lis  19900630   <NA>
    2  Qianl  19920709 female
    3  Wangw  19891203   male
    4 Zhangs  19900103   male
    # 合并[[2]]和height
    [[3]]
        name birthtime    sex height
    1    Lis  19900630   <NA>    158
    2  Qianl  19920709 female    162
    3  Wangw  19891203   male    178
    4 Zhangs  19900103   male     NA
    
    # 累加
    > accumulate(1:5,`+`)
    [1]  1  3  6 10 15
    > cumsum(1:5)
    [1]  1  3  6 10 15
    

    相关文章

      网友评论

        本文标题:91.for循环的其他模式

        本文链接:https://www.haomeiwen.com/subject/tfvecrtx.html