## 10.6 归约累计函数

reduce、accumulate()函数用法介绍.

### 10.6.1 reduce 函数

reduce() 将多个元素的值组合(由函数驱动)成一个，组合的动词(函数)由参数.f决定。

reduce(.x, .f, ..., .init, .dir = c("forward", "backward"))

reduce2(.x, .y, .f, ..., .init)

reduce(1:100,+)
#> [1] 5050

reduce(5:1,-)
#> [1] -5
# 等同于
5-4-3-2-1
#> [1] -5

.dir 参数决定动词(函数)方向：

str(reduce(1:4, list))
#> List of 2
#>  $:List of 2 #> ..$ :List of 2
#>   .. ..$: int 1 #> .. ..$ : int 2
#>   ..$: int 3 #>$ : int 4
# 等同
# list(list(list(list(1),2),3),4)
str(reduce(1:4, list, .dir = "backward"))
#> List of 2
#>  $: int 1 #>$ :List of 2
#>   ..$: int 2 #> ..$ :List of 2
#>   .. ..$: int 3 #> .. ..$ : int 4
# 等同
# list(1,list(2,list(3,list(4))))

n <- 10
dt1 <- data.frame(a=letters[n],b1=rnorm(n))
dt2 <- data.frame(a=letters[n],b2=rnorm(n))
dt3 <- data.frame(a=letters[n],b3=rnorm(n))
dt4 <- data.frame(a=letters[n],b4=rnorm(n))

reduce(list(dt1,dt2,dt3,dt4),merge) %>%
#>   a     b1     b2   b3      b4
#> 1 j -0.387 -0.209 2.04 -1.1462
#> 2 j -0.387 -0.209 2.04  0.8462
#> 3 j -0.387 -0.209 2.04  0.0817
#> 4 j -0.387 -0.209 2.04 -1.3051
#> 5 j -0.387 -0.209 2.04 -0.9449
#> 6 j -0.387 -0.209 2.04  0.4543
# not run
# reduce(list(dt1,dt2,dt3,dt4),merge,by='a') same above

paste2 <- function(x, y, sep = ".") paste(x, y, sep = sep)
letters[1:4] %>% reduce(paste2)
#> [1] "a.b.c.d"
letters[1:4] %>% reduce2(c("-", ".", "-"), paste2)
#> [1] "a-b.c-d"
x <- list(c(0, 1), c(2, 3), c(4, 5))
y <- list(c(6, 7), c(8, 9))
reduce2(x, y, paste)
#> [1] "0 2 6 4 8" "1 3 7 5 9"

### 10.6.2 accumulate 函数

accumulate()reduce()的区别是accumulate()记录过程结果，而reduce()仅保持最后结果。

1:5 %>% accumulate(+)
#> [1]  1  3  6 10 15
1:5 %>% accumulate(+, .dir = "backward")
#> [1] 15 14 12  9  5
accumulate(letters[1:5], paste, sep = ".")
#> [1] "a"         "a.b"       "a.b.c"     "a.b.c.d"   "a.b.c.d.e"
paste2 <- function(x, y, sep = ".") paste(x, y, sep = sep)
letters[1:4] %>% accumulate(paste2)
#> [1] "a"       "a.b"     "a.b.c"   "a.b.c.d"
letters[1:4] %>% accumulate2(c("-", ".", "-"), paste2)
#> [[1]]
#> [1] "a"
#>
#> [[2]]
#> [1] "a-b"
#>
#> [[3]]
#> [1] "a-b.c"
#>
#> [[4]]
#> [1] "a-b.c-d"`