Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/r/79.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
R 生成要合成的值索引,但以可伸缩的方式忽略初始值_R_Dplyr_Lag_Mutate - Fatal编程技术网

R 生成要合成的值索引,但以可伸缩的方式忽略初始值

R 生成要合成的值索引,但以可伸缩的方式忽略初始值,r,dplyr,lag,mutate,R,Dplyr,Lag,Mutate,我试图生成一个从返回数据派生的索引 我要生成的新列将通过取100,然后将其复合得到。对于此示例: 第一个值=100 第二个值=第一个值*(1+10/100)=110 第三个值=第二个值*(1+20/100)=132,依此类推 请注意,第一个返回值5需要忽略。我知道我可以覆盖它来完成我想要的,但是我想知道是否有更优雅的方法来获得所需的输出 我接近得到我想要的,但我需要忽略5的第一次返回。新科勒的预期产量将为100、110、132 **Reproducible example** # Lo

我试图生成一个从返回数据派生的索引

我要生成的新列将通过取100,然后将其复合得到。对于此示例:

第一个值=100

第二个值=第一个值*(1+10/100)=110

第三个值=第二个值*(1+20/100)=132,依此类推

请注意,第一个返回值5需要忽略。我知道我可以覆盖它来完成我想要的,但是我想知道是否有更优雅的方法来获得所需的输出

我接近得到我想要的,但我需要忽略5的第一次返回。新科勒的预期产量将为100、110、132

**Reproducible example**

    # Load package
    library(tidyverse)

    # Create data
    df <- data.frame(asset = c("A", "A", "A"), return = c(5,10,20))
    df

# Generate new column
test <- df %>%
  mutate(new_col = 100) %>%   #initialize
  mutate(new_col = ifelse(row_number(new_col) == 1,
                          new_col,
                          lag(new_col, 1) * cumprod((1 + return/100))
                          )
         )
test
**可复制示例**
#加载包
图书馆(tidyverse)
#创建数据
df%#初始化
变异(新列=ifelse(行号(新列)==1,
新科,
滞后(新列,1)*cumprod((1+返回/100))
)
)
测试

提前谢谢

一个选项是
累积

library(tidyverse)
df %>% 
   mutate(newcol = accumulate(return[-1], ~ .x* (1 + .y/100), .init = 100))
#  asset return newcol
#1     A      5    100
#2     A     10    110
#3     A     20    132

或者使用
cumprod

df %>% 
    mutate(newcol = cumprod( c(100, 1 + return[-1]/100)))

或基本R中的类似选项

Reduce(function(x, y) x * (1 + y/100), df$return[-1], init = 100, accumulate = TRUE)
#[1] 100 110 132

或使用
for
循环

df$newcol[1] <- 100
for(i in 2:nrow(df)) df$newcol[i] <- df$newcol[i-1] * (1 + df$return[i]/100)
数据
df1-Akrun,这非常有用。你能解释一下这个解决方案吗?我不太熟悉“~”操作符,它在这里做什么,以及.x如何表示返回列,以及.y如何表示newcol。我阅读了文档,但不清楚reduce是否是在不调用函数的情况下隐含的,也不清楚这是否适用于3个以上的参数(例如.z)。谢谢事实上,如果你不介意的话,还有一个相关的问题。我的真实数据集有许多列,我想对这些列执行此操作。我试图使用mutate_at,但无法使其工作,所以我使用了这个更简单的示例,从只有一个资产的地方开始column@DaveM它确实有效。e、 g.
df%mutate\u at(vars(以('return')开头)、list(newcol=~acculate(.[-1]、~.x*(1+.y/100)、.init=100))
。我不是故意暗示它不起作用。我的意思是,当我尝试之前的一次尝试时(在你回答之前),我无法让它工作。@DaveM没问题。你可能错过了一个
~
什么的
df1 %>% 
    mutate_at(vars(starts_with('return')), 
      list(newcol = ~  accumulate(.[-1], ~ .x * (1+ .y/100), .init = 100)))
#   asset return return2 return_newcol return2_newcol
#1     A      5      15           100            100
#2     A     10      12           110            112
#3     A     20      25           132            140
df1 <- data.frame(asset = c("A", "A", "A"), 
      return = c(5,10,20), return2 = c(15, 12, 25))