R传递函数进行累加 [英] R pass function to accumulate
本文介绍了R传递函数进行累加的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!
问题描述
我想使用这个累加示例来更改数据FARME中某个变量的固定增长。原例:https://community.rstudio.com/t/row-wise-iteration-in-a-dataframe-where-each-row-depends-on-previous-values/38725/2
library(dplyr)
library(purrr)
x <- tibble(a = c(1:10),
b = c(seq(100, 140, 10), rep(NA_real_, 5)) )
x$growth = runif(10, 0.001, 0.09)
fill_in <- function(prev, new, growth = 0.03) {
if_else(!is.na(new), new, prev * (1 + growth))
}
x <- x %>%
mutate(b = accumulate(b, fill_in))
这是可行的,但我不能用x$Growth替换0.03。有帮助吗?
推荐答案
由于accumulate
(和accumulate2
)的结构,我们不能只迭代b
,我们需要为每个点包括类似c(b, growth)
的内容。为此,我们不会传递b
,而是传递一个list
向量,它可以用:
with(x, pmap(list(b, growth), c))
# [[1]]
# [1] 100.0000000 0.0265944
# [[2]]
# [1] 110.00000000 0.07115916
# [[3]]
# [1] 120.00000000 0.03739895
# [[4]]
# [1] 130.00000000 0.07958855
# [[5]]
# [1] 140.00000000 0.08470159
# [[6]]
# [1] NA 0.005054528
# [[7]]
# [1] NA 0.04800139
# [[8]]
# [1] NA 0.08042529
# [[9]]
# [1] NA 0.05007772
# [[10]]
# [1] NA 0.04163871
有了这个,我们现在可以累计:
fill_in2 <- function(prev, new) if (is.na(new[1])) prev[1]*(1+new[2]) else new[1]
options(pillar.sigfig = 5)
x %>%
mutate(b = accumulate(pmap(list(b, growth), c)[-1], .init = b[1], fill_in2))
# # A tibble: 10 x 3
# a b growth
# <int> <dbl> <dbl>
# 1 1 100 0.026594
# 2 2 110 0.071159
# 3 3 120 0.037399
# 4 4 130 0.079589
# 5 5 140 0.084702
# 6 6 140.71 0.0050545
# 7 7 147.46 0.048001
# 8 8 159.32 0.080425
# 9 9 167.30 0.050078
# 10 10 174.27 0.041639
我同时执行pmap(..)[-1]
和.init=b[1]
的原因是,使用accumulate
的默认行为,.x
的第一个元素是按原样传递的;在这种情况下,这将作为第一个返回值传递c(100, 0.0266)
,这不是我们想要的。为解决此问题,我们将其从pmap
列表中删除,并将b[1]
添加为accumulate
的初始化值(.init=
)。
btw:这是使用growth
的当前值应用于b
的上一个值。
fill_in
已使用if_else
。虽然它有效,但它是不必要的,也是不合适的。如果要查找长度始终为1的if
对象,则使用if
(也可以使用else
);如果要查找向量的条件,则使用ifelse
/if_else
。虽然当您知道if_else
的长度始终为1时,可以使用if_else
,但开销和可能发生的其他事情是完全不必要的(在基本R中,ifelse
会对非平凡的类数据产生后果和副作用,因此应该对其使用进行管理)。
由于accumulate
一次只使用一行数据调用函数,因此使用if
更合适。
数据
set.seed(123)
x <- tibble(a = c(1:10),
b = c(seq(100, 140, 10), rep(NA_real_, 5)),
growth = runif(10, 0.001, 0.09))
这篇关于R传递函数进行累加的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!
查看全文