Construct a loop based on multiple conditions in a column R

[亡魂溺海] 提交于 2021-02-20 01:35:00

问题


I have a df attached and I would like to create a loop that would apply a specific sequence based on conditions in column "x9". I would like to be able to set the sequence myself so I can try different sequences for this data frame, I will explain more below.

I have a df of losses and wins for an algorithm. On the first instance of a win I want to take the value in "x9" and divide it by the sequence value. I want to keep iterating through the sequence values until a loss is achieved. Once a loss is achieved the sequence will restart.

Risk control is the column I am attempting to create, it takes values from "x9" and divides them by the sequence value. I want to have the ability to alter the sequence values.

In short I need assistance in:

  1. Constructing a sequence to apply to my df, would like to be able to alter this to try different sequences;
  2. Take values in "x9" and create a new column that would apply the sequence values set. The sequence is taking the value in "x9" and dividing it by the sequence number;
  3. Construct a loop to iterate through the entire df to apply this over all of the values.

I would appreciate any help / insight anyone can provide.

structure(list(x1 = c(1, 2, 3, 4, 5, 6, 7, 8, 9, 10), x2 = c("2016.01.04 01:05", 
"2016.01.04 01:12", "2016.01.04 01:13", "2016.01.04 01:17", "2016.01.04 01:20", 
"2016.01.04 01:23", "2016.01.04 01:25", "2016.01.04 01:30", "2016.01.04 01:31", 
"2016.01.04 01:59"), x3 = c("buy", "close", "buy", "close", "buy", 
"close", "buy", "t/p", "buy", "close"), x4 = c(1, 1, 2, 2, 3, 
3, 4, 4, 5, 5), x5 = c(8.46, 8.46, 8.6, 8.6, 8.69, 8.69, 8.83, 
8.83, 9, 9), x6 = c(1.58873, 1.58955, 1.5887, 1.58924, 1.58862, 
1.58946, 1.58802, 1.58902, 1.58822, 1.58899), x7 = c(1.57873, 
1.57873, 1.5787, 1.5787, 1.57862, 1.57862, 1.57802, 1.57802, 
1.57822, 1.57822), x8 = c(1.58973, 1.58973, 1.5897, 1.5897, 1.58962, 
1.58962, 1.58902, 1.58902, 1.58922, 1.58922), x9 = c("$0.00", 
"$478.69", "$0.00", "$320.45", "$0.00", "$503.70", "$0.00", "$609.30", 
"$0.00", "$478.19"), x10 = c("$30,000.00", "$30,478.69", "$30,478.69", 
"$30,799.14", "$30,799.14", "$31,302.84", "$31,302.84", "$31,912.14", 
"$31,912.14", "$32,390.33"), `Risk Control` = c(NA, "$478.69", 
NA, "$320.45", NA, "$251.85", NA, "$304.65", NA, "$159.40"), 
    Sequence = c(NA, 1, NA, 1, NA, 2, NA, 2, NA, 3)), row.names = c(NA, 
-10L), class = c("tbl_df", "tbl", "data.frame"), spec = structure(list(
    cols = list(x1 = structure(list(), class = c("collector_double", 
    "collector")), x2 = structure(list(), class = c("collector_character", 
    "collector")), x3 = structure(list(), class = c("collector_character", 
    "collector")), x4 = structure(list(), class = c("collector_double", 
    "collector")), x5 = structure(list(), class = c("collector_double", 
    "collector")), x6 = structure(list(), class = c("collector_double", 
    "collector")), x7 = structure(list(), class = c("collector_double", 
    "collector")), x8 = structure(list(), class = c("collector_double", 
    "collector")), x9 = structure(list(), class = c("collector_character", 
    "collector")), x10 = structure(list(), class = c("collector_character", 
    "collector")), `Risk Control` = structure(list(), class = c("collector_character", 
    "collector")), ...12 = structure(list(), class = c("collector_logical", 
    "collector")), Sequence = structure(list(), class = c("collector_double", 
    "collector"))), default = structure(list(), class = c("collector_guess", 
    "collector")), delim = ","), class = "col_spec"))

回答1:


Maybe there are better ways but I believe the following function does what the question asks for. It takes two arguments, a vector x to be processed and a sequence Seq. The return value is the risk control described in the question.

constructRisk <- function(x, Seq){
  stopifnot(length(x) > 0)
  stopifnot(length(Seq) > 0)
  n <- length(x)
  m <- length(Seq)
  y <- numeric(n)
  iSeq <- 1L
  for(i in seq_len(n)){
    y[i] <- x[i]/Seq[iSeq]
    if(!is.na(y[i])){
      if(y[i] < 0) iSeq <- 0L
    }
    iSeq <- iSeq + 1L
    if(iSeq > m) iSeq <- 1L
  }
  y
}

Note that since the posted data has column x9 with dollar signs and is, therefore, of class "character", the test below is on a numeric version of it, X9. And the same goes for the risk control column, as posted.

X9 <- as.numeric(sub("\\$", "", df1$x9))
RskCntr <- as.numeric(sub("\\$", "", df1$`Risk Control`))

RC <- constructRisk(X9, df1$Sequence)

all.equal(RskCntr, RC)
#[1] "Mean relative difference: 2.091175e-05"
all.equal(RskCntr, round(RC, 2))
#[1] TRUE


来源:https://stackoverflow.com/questions/64799485/construct-a-loop-based-on-multiple-conditions-in-a-column-r

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!