10.6 归约累计函数
reduce、accumulate()函数用法介绍.
10.6.1 reduce 函数
reduce()
将多个元素的值组合(由函数驱动)成一个,组合的动词(函数)由参数.f决定。
reduce(.x, .f, ..., .init, .dir = c("forward", "backward"))
reduce2(.x, .y, .f, ..., .init)
如下,将 1 到 100 共 100 个元素由函数+
组合成一个元素,即将 100 个数字连续相加:
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))))
自己试着比较添加 .dir 参数后的差异。
在实际工作中,我常用reduce函数实现连续merge()
或left_joind()
等功能,如下所示:
<- 10
n <- data.frame(a=letters[n],b1=rnorm(n))
dt1 <- data.frame(a=letters[n],b2=rnorm(n))
dt2 <- data.frame(a=letters[n],b3=rnorm(n))
dt3 <- data.frame(a=letters[n],b4=rnorm(n))
dt4
reduce(list(dt1,dt2,dt3,dt4),merge) %>%
head()
#> 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
关于reduce2()
函数,第二个元素需要比第一个元素长度少一个,如下所示:
<- function(x, y, sep = ".") paste(x, y, sep = sep)
paste2 1:4] %>% reduce(paste2)
letters[#> [1] "a.b.c.d"
1:4] %>% reduce2(c("-", ".", "-"), paste2)
letters[#> [1] "a-b.c-d"
<- list(c(0, 1), c(2, 3), c(4, 5))
x <- list(c(6, 7), c(8, 9))
y 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"
<- function(x, y, sep = ".") paste(x, y, sep = sep)
paste2 1:4] %>% accumulate(paste2)
letters[#> [1] "a" "a.b" "a.b.c" "a.b.c.d"
1:4] %>% accumulate2(c("-", ".", "-"), paste2)
letters[#> [[1]]
#> [1] "a"
#>
#> [[2]]
#> [1] "a-b"
#>
#> [[3]]
#> [1] "a-b.c"
#>
#> [[4]]
#> [1] "a-b.c-d"