好的,这是我想用dplyr实现的全部视图:
使用dplyr我正在进行计算以形成新列 .
initial.capital -
x.long.shares -
x.end.value -
x.net.profit -
new.initial.capital
执行此操作的代码:
# Calculate Share Prices For Each ETF
# Initialize Start Capital Column
library(dplyr)
library(data.table)
df$inital.capital <- 10000
output <- df %>%
dplyr::mutate(RunID = data.table::rleid(x.long)) %>%
group_by(RunID) %>%
dplyr::mutate(x.long.shares = ifelse(x.long == 0,0,
ifelse(row_number() == n(),
first(inital.capital) / first(close.x),0))) %>%
dplyr::mutate(x.end.value = ifelse(x.long == 0,0,
ifelse(row_number() == n(),
last(x.long.shares) * last(close.x),0))) %>%
dplyr::mutate(x.net.profit = ifelse(x.long == 0,0,
ifelse(row_number() == n(),
last(initial.capital) - last(x.end.value),0))) %>%
dplyr::mutate(new.initial.capital = ifelse(x.long == 0,0,
ifelse(row_number() == n(),
last(x.net.profit) + last(inital.capital),0))) %>%
ungroup() %>%
select(-RunID)
我按x.long列分组 . 并在分组时 . 使用组内的第一个/最后一个位置从不同列进行计算我的基本问题是:
在照片中,请参阅new.initial.capital列下的红色突出显示 . 如何“保存”此值(10185.33)...并将其插入NEXT组,将其保存在initial.capital列下,再次以红色突出显示(它将替换10,000或将其存储在组的第一行) ?
编辑
我真正需要做的是将new.initial.capital列中的最终值保存到变量中 . 然后这个变量可以在下一组中使用(参见下面的代码)这里的值将用作下一组计算的一部分...然后当更新结束new.initial.capital时,这个值进入变量,然后它转到下一组的开头(见下面的代码)..然后所有的值将再次更新....变量将放在这里:
output <- df %>%
dplyr::mutate(RunID = data.table::rleid(x.long)) %>%
group_by(RunID) %>%
dplyr::mutate(x.long.shares = ifelse(x.long == 0,0,
ifelse(row_number() == n(),
first(end_of_new.initial.capital_variable_from_previous_group) / first(close.x),0))) %>%
我基本上想在dplyr组之间传递值 . 这可能吗?或者我每次都可以将它存储在变量中?
下面是照片中的一些示例数据:保存到.txt
df <- read.table("your_dir\df.txt",header=TRUE, sep="", stringsAsFactors=FALSE)
close.x x.long y.short x.short y.long inital.capital x.long.shares x.end.value x.net.profit new.initial.capital
37.96 NA NA NA NA 10000 NA NA NA NA
36.52 0 0 0 0 10000 0 0 0 0
38.32 0 0 0 0 10000 0 0 0 0
38.5504 0 0 0 0 10000 0 0 0 0
38.17 0 0 0 0 10000 0 0 0 0
38.85 1 1 0 0 10000 0 0 0 0
38.53 1 1 0 0 10000 0 0 0 0
39.13 1 1 0 0 10000 0 0 0 0
38.13 1 1 0 0 10000 257.4002574 9814.671815 185.3281853 10185.32819
37.01 0 0 1 1 10000 0 0 0 0
36.14 0 0 1 1 10000 0 0 0 0
35.27 0 0 1 1 10000 0 0 0 0
35.13 0 0 1 1 10000 0 0 0 0
32.2 0 0 1 1 10000 0 0 0 0
33.03 1 1 0 0 10000 0 0 0 0
34.94 1 1 0 0 10000 0 0 0 0
34.57 1 1 0 0 10000 0 0 0 0
33.6 1 1 0 0 10000 0 0 0 0
34.34 1 1 0 0 10000 302.7550711 10396.60914 -396.6091432 9603.390857
35.86 0 0 1 1 10000 0 0 0 0
我试过了什么
我试着做一个变量:
inital.capital <- 10000
并在代码中插入...
output <- df %>%
dplyr::mutate(RunID = data.table::rleid(x.long)) %>%
group_by(RunID) %>%
dplyr::mutate(x.long.shares = ifelse(x.long == 0,0,
ifelse(row_number() == n(),
initial.capital / first(close.x),0))) %>% # place initial.capital variable.. initialized with 10000
dplyr::mutate(x.end.value = ifelse(x.long == 0,0,
ifelse(row_number() == n(),
last(x.long.shares) * last(close.x),0))) %>%
dplyr::mutate(x.net.profit = ifelse(x.long == 0,0,
ifelse(row_number() == n(),
last(initial.capital) - last(x.end.value),0))) %>%
dplyr::mutate(new.initial.capital = ifelse(x.long == 0,0,
ifelse(row_number() == n(),
last(x.net.profit) + last(inital.capital),0))) %>%
dplyr::mutate(new.initial.capitals = ifelse(x.long == 0,0,
ifelse(row_number() == n(),
inital.capital < - last(new.initial.capital),0))) %>% # update variable with the final balance of new.inital.capital column
ungroup() %>%
select(-RunID)
如果我每次都可以更新initial.capital变量 . 然后,这将作为组之间的“链接” . 但是,这个想法目前还没有在dplyr设置中工作 .
任何协助赞赏 .
6 回答
你在问题中使用data.table并标记了data.table这个问题,所以这里是一个data.table答案 . 当
j
计算时,它处于静态范围内,其中局部变量保留其来自前一组的值 .使用虚拟数据来演示:
到目前为止,足够简单 .
请注意,
prev
值未更新,因为prev
和ans
是j
范围内的局部变量,这些变量在每个组运行时都会更新 . 为了说明,可以使用R的<<-
运算符从每个组内更新全局prev
:但是没有必要在data.table中使用
<<-
,因为局部变量是静态的(保留它们之前组的值) . 除非您在查询完成后需要使用最终组的值 .你_1125112_优雅' pure-dplyr solution, because dplyr isn' t真的是为了做到这一点 . dplyr喜欢做的是分别使用窗口和汇总函数的map / reduce类型操作(
mutate
和summarize
) . 你究竟是什么,因为你希望每个组都依赖于最后一个,所以你真的在描述一个带有副作用的循环操作 - 两个非R-philosophy操作 .如果你想破解你所描述的方式,你可以尝试这样的方法:
但是,这实际上不是一个非常友好的R代码,因为它取决于副作用和循环 . 如果你想与dplyr集成,我建议你看看你是否可以根据摘要和/或窗口函数重新计算你的计算 .
更多:
https://www.rstudio.com/wp-content/uploads/2015/02/data-wrangling-cheatsheet.pdf
https://danieljhocking.wordpress.com/2014/12/03/lags-and-moving-means-in-dplyr/
这种使用第一个和最后一个是非常不整洁的,所以我们将保持最新的一步 .
首先,我们按照您的代码构建中间数据,但添加一些列以便稍后在正确的位置加入 . 我不确定你是否需要保留所有列,否则你不需要第二次加入 .
然后我们构建汇总数据,我按照你的意思稍微重构了你的代码,因为这些操作“应该”是行的 .
然后我们将我们的汇总表加入到原始表中,充分利用了第一步的技巧 . 如果您不需要所有列,则可以跳过第一个连接 .
data
我花了很长时间才明白你的目标:单一的“更新”,这有用吗?
在此之后,根据上面的分组
row_number
,使用pass.value
列替换initial.capital
的值 .我不太确定如何在没有循环这个更新程序的情况下解决这个问题,我想如果你想做这样的10,000次更新,那肯定会是一个无赖 . 但它将使您能够将值“传递”到第二个红色单元格中图片 .
滚动这样的值可能非常困难 . 我认为最好在顶部加上一条作为交易的线,其净效应是为您的基本资本增加10k . 然后,您可以使用偏移量的累积总和来相对轻松地实现您正在寻找的内容:
pdf = df %>% group_by(group) %>% arrange(dates) %>% mutate(cs = cumsum(sales))
代码复制自r cumsum per group in dplyr
我决定重新审视这个问题,这是一个解决方案,按行业分组
signal
,制作交易组ID的开始和结束 . 之后,使用普通for loop
对ifelse
语句进行计算并更新组之间的运行变量:shares
,total_start_capital
和total_end_capital
. 这些允许将变量从交易转移到下一个交易,并用于每个连续的交易计算 . 如果只允许dplyr
更新组之间的变量 . 如果有人想要使用PnL $与%rets创建自己的后台测试脚本,这就有 Value .使用所需的输出: