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