R 对自己的前一个输出进行操作的递归函数

R 对自己的前一个输出进行操作的递归函数,r,loops,recursion,matrix,dataframe,R,Loops,Recursion,Matrix,Dataframe,我有一个特定基准年的价格(在本例中为1993年),以及所有年份的乘数。使用这些已知的乘法因子,我想计算基准年前后所有年份的(项目)价格 以下是输入数据: Year City MultiplicationFactor Price_BaselineYear 1990 New York NA NA 1991 New York 0.9 NA 1992 New York 2.

我有一个特定基准年的价格(在本例中为1993年),以及所有年份的乘数。使用这些已知的乘法因子,我想计算基准年前后所有年份的(项目)价格

以下是输入数据:

Year    City    MultiplicationFactor    Price_BaselineYear
1990    New York          NA            NA
1991    New York          0.9           NA
1992    New York          2.0           NA
1993    New York          0.8           100
1994    New York          0.6           NA
1995    New York          0.8           NA
1996    New York          2.0           NA
1990    Boston             NA           NA
1991    Boston             1.6          NA
1992    Boston             1.25         NA
1993    Boston             0.5          200
1994    Boston             1.75         NA
1995    Boston             2.5          NA
1996    Boston             0.5          NA
用于构造输入数据的代码:

myData<-structure(list(Year = c(1990L, 1991L, 1992L, 1993L, 1994L, 1995L,1996L, 1990L, 1991L, 1992L, 1993L, 1994L, 1995L, 1996L), City = structure(c(2L,2L, 2L, 2L, 2L, 2L, 2L, 1L, 1L, 1L, 1L, 1L, 1L, 1L), .Label = c("Boston","New York"), class = "factor"), MultiplicationFactor = c(NA,0.9, 2, 0.8, 0.6, 0.8, 2, NA, 1.6, 1.25, 0.5, 1.75, 2.5, 0.5),`Price(BaselineYear)` = c(NA, NA, NA, 100L, NA, NA, NA, NA,NA, NA, 200L, NA, NA, NA)), .Names = c("Year", "City", "MultiplicationFactor","Price_BaselineYear"), class = c("tbl_df", "tbl", "data.frame"), row.names = c(NA, -14L))
以下是我迄今为止通过@alistaire获得的信息:

myData %>%
  group_by(City) %>%
  arrange(Year) %>%
  mutate(Price_AllYears = ifelse(Year < Year[which(!is.na(Price_BaselineYear))], 
                        lead(Price_AllYears) / lead(MultiplicationFactor),
                        ifelse(Year > Year[which(!is.na(Price_BaselineYear))],
                               lag(Price_AllYears) * MultiplicationFactor,
                               Price_BaselineYear)))%>%
  ungroup() %>% 
  arrange(City)

fun
向这些行输入一组行号、子集
MyData
,并确定基值的索引,
ix.base
。首先检查是否只有一个基准价格,如果没有,则返回NA;否则,计算基数之前的乘数,
hd
,基数之后的乘数,
tl
。对于每一种情况,我们都可以使用
cumprod
,以避免问题中电子表格公式中显示的迭代计算类型。最后将计算出的乘数乘以基准价格。使用
ave
将其应用于每个城市。未使用任何软件包:

fun <- function(ix) with(MyData[ix, ], {
  ix.base <- which(!is.na(Price_BaselineYear))
  if (length(ix.base) != 1) return(NA)
  hd <- rev(cumprod(rev(1/head(MultiplicationFactor, ix.base)[-1])))
  tl <- cumprod(tail(MultiplicationFactor, - ix.base))
  Price_BaselineYear[ix.base] * c(hd, 1, tl)
})
transform(MyData, Price_AllYears = ave(seq_along(Year), City, FUN = fun))

我猜这个问题是几个小时前发布的。还有,这些评论要求更新以前的问题。@akrun Right:即使在这里,第一条评论说“这应该是对旧问题的编辑或评论,而不是新问题。”所以这可能是这个问题的第三次迭代……谢谢大家!谢谢你,格洛森迪克。它适用于上面的示例数据集,但当我将其用于更大的数据集时,我得到了这个错误“error:length(n)==1L不是真的”,我添加了一个基线存在性检查,以防万一。可能还有其他错误或角落案例也会从检查中受益,但希望上面给出了想法,您可以根据实际数据与问题中显示的数据之间存在的差异从中吸取教训。
    A       B       C                       D                   E
1   Year    City    MultiplicationFactor    Price_BaselineYear  Price_AllYears
2   1990    New York    NA                  NA                  E3/C3
3   1991    New York    0.9                 NA                  E4/C4
4   1992    New York    2.0                 NA                  E5/C5
5   1993    New York    0.8                 100                 D5
6   1994    New York    0.6                 NA                  E5*C6
7   1995    New York    0.8                 NA                  E6*C7
8   1996    New York    2.0                 NA                  E7*C8
9   1990    Boston      NA                  NA                  E10/C10
10  1991    Boston      1.6                 NA                  E11/C11
11  1992    Boston      1.25                NA                  E12/C12
12  1993    Boston      0.5                 200                 D12
13  1994    Boston      1.75                NA                  E12*C13
14  1995    Boston      2.5                 NA                  E13*C14
15  1996    Boston      0.5                 NA                  E14*C15
fun <- function(ix) with(MyData[ix, ], {
  ix.base <- which(!is.na(Price_BaselineYear))
  if (length(ix.base) != 1) return(NA)
  hd <- rev(cumprod(rev(1/head(MultiplicationFactor, ix.base)[-1])))
  tl <- cumprod(tail(MultiplicationFactor, - ix.base))
  Price_BaselineYear[ix.base] * c(hd, 1, tl)
})
transform(MyData, Price_AllYears = ave(seq_along(Year), City, FUN = fun))
   Year     City MultiplicationFactor Price_BaselineYear Price_AllYears
1  1990 New York                   NA                 NA         69.444
2  1991 New York                 0.90                 NA         62.500
3  1992 New York                 2.00                 NA        125.000
4  1993 New York                 0.80                100        100.000
5  1994 New York                 0.60                 NA         60.000
6  1995 New York                 0.80                 NA         48.000
7  1996 New York                 2.00                 NA         96.000
8  1990   Boston                   NA                 NA        200.000
9  1991   Boston                 1.60                 NA        320.000
10 1992   Boston                 1.25                 NA        400.000
11 1993   Boston                 0.50                200        200.000
12 1994   Boston                 1.75                 NA        350.000
13 1995   Boston                 2.50                 NA        875.000
14 1996   Boston                 0.50                 NA        437.500