【问题标题】:I'm stuck in a task with FOR and IF functions in R data programming我在 R 数据编程中遇到了 FOR 和 IF 函数的任务
【发布时间】:2021-01-02 10:27:31
【问题描述】:

所以目前我遇到了 FOR 和 IF 函数的问题。

我有一个完整的工作代码,如下所示:

#my data input
demand.variation=c(1,4,20,23,37)
demand.probability=c(0.81,0.85,0.89,0.93,0.97)
n.month=25

#generating result matrix
result=matrix(0,n.month,2)
colnames(result)=c("Month","Demand")

#filling result matrix with month index and random demand value
result[,1]=1:n.month
random=runif(n.month,0,1)

#return demand value based on random value
for (i in seq_along(random)) {
  if (random[i]>demand.probability[5]) result[i,2]=demand.variation[5]
  else if (random[i]>demand.probability[4]) result[i,2]=demand.variation[4]
  else if (random[i]>demand.probability[3]) result[i,2]=demand.variation[3]
  else if (random[i]>demand.probability[2]) result[i,2]=demand.variation[2]
  else if (random[i]>demand.probability[1]) result[i,2]=demand.variation[1]
  else result[i,2]=0
}

#final result
result

结果完全可以使用:

> result
      Month Demand
 [1,]     1      0
 [2,]     2      0
 [3,]     3      0
 [4,]     4      0
 [5,]     5      0
 [6,]     6      0
 [7,]     7      0
 [8,]     8      0
 [9,]     9      4
[10,]    10      0
[11,]    11      0
[12,]    12     23
[13,]    13     37
[14,]    14      0
[15,]    15      1
[16,]    16      0
[17,]    17      0
[18,]    18      0
[19,]    19      1
[20,]    20     20
[21,]    21      0
[22,]    22      0
[23,]    23      0
[24,]    24      0
[25,]    25      0

问题是,我必须重新运行相同的代码,但 demand.variation 和 demand.probability 的长度和值不同,所以我将面临这两个变量的几十个变化的问题,因为 FOR 和 IF 是手动输入。

我的问题是如何生成灵活的 FOR 和 IF 语句代码来覆盖#return demand value based on random value 代码的工作。

脚注:demand.variation 和 demand.probability 将始终具有相同的向量长度,并相应地相互连接,这意味着 demand.variation 向量中的第一个值有demand.probability 向量中的第一个值的概率,等等

demand.variation=c(1,4,20,23,37)
demand.probability=c(0.81,0.85,0.89,0.93,0.97)

如果您能在这方面帮助我,我将不胜感激。

【问题讨论】:

  • 您是否尝试过您之前帖子中的findInterval 答案。这对于任何长度的向量都应该是通用的。 stackoverflow.com/a/65536884
  • 嗨,谢谢你帮助我,因为之前的答案似乎已经解决了我的问题,所以我没有尝试过你的建议。我将与其他建议一起尝试,并找出哪个最有效。还是谢谢

标签: r for-loop if-statement


【解决方案1】:

您可以添加另一个 for() 循环,从 demand.variation 向量中的条目数倒数。

for(i in seq_along(random)){
  for(j in seq_along(demand.variation):1){
    if(random[i] > demand.probability[j]){
      result[i,2] <-  demand.variation[j]
    } else {
      result[i,2] <- 0
    }
  }
}

编辑:澄清:

所以我把你想要的东西分解成几个函数,并组合成一个主函数,可以根据需要的任何长度/组合调用:

create.demand.variation <- function(vector){
  return(demand.probability <- c(vector))
}

create.demand.probability <- function(vector){
  return(demand.probability <- c(vector))
}

create.random <- function(n.month){
  return(random <- runif(n.month, 0, 1))
}

create.result <- function(n.month){
  result=matrix(0,n.month,2)
  colnames(result)=c("Month","Demand")
  result[,1]=1:n.month
  return(result)
}

create.random <- function(n.month){
  return(random <- runif(n.month,0,1))
}

get.result <- function(demand.variation, demand.probability, random.vector, result){
  for(i in 1:length(random)){
    k <- length(demand.probability)
    while(k >= 1){
      if(random[i] > demand.probability[k]){
        result[i,2] <- demand.variation[k]
        k <- 0
      } else {
        k <- k - 1
      }
    }
  }
  return(result)
}

master.function <- function(vector.demand, vector.prob, n.month ){
  create.demand.variation(vector.demand) -> demand.variation
  create.demand.probability(vector.prob) -> demand.probability
  create.random(n.month) -> random.vector
  create.result(n.month) -> result
  get.result(demand.variation, demand.probability, random.vector, result) -> result
  return(result)
}

所以对于示例向量,您可以输入:

master.function(c(1,4,20,23,37), c(0.81, 0.85, 0.89, 0.93, 0.97), 25) -> 
result

对我来说,这会产生:

> result
      Month Demand
 [1,]     1      0
 [2,]     2     20
 [3,]     3      0
 [4,]     4      0
 [5,]     5      0
 [6,]     6      0
 [7,]     7      1
 [8,]     8      0
 [9,]     9      4
[10,]    10      0
[11,]    11     20
[12,]    12      0
[13,]    13     23
[14,]    14      0
[15,]    15      0
[16,]    16      0
[17,]    17      0
[18,]    18      0
[19,]    19      0
[20,]    20      0
[21,]    21      0
[22,]    22      0
[23,]    23      0
[24,]    24      0
[25,]    25      1

【讨论】:

  • 感谢您的回答。我试图在我的程序上使用你的代码,但它似乎没有按照我想要的方式工作。此外,我收到 25 条警告告诉我:(在 seq_along(demand.variation):1 中:数值表达式有 5 个元素:仅使用第一个元素。)我会在对您的代码进行一些研究和修改后回来,现在它仍然没有解决我的问题。
  • 奇怪的是我使用它并收到了非错误输出。稍后我会处理它,看看我是否可以为您改进它。
  • 所以我检查了您的代码并发现:您的代码仅提供 2 种输出可能性,即 demand.variation[j] 和 0。我的意图是如果 random[i] 不是 > 需求。 probability[j],它应该检查 random[i] 是否 > demand.probability[j-1],并继续检查直到 demand.probability 向量上的第一个值。如果最后 random[i] 小于 demand.probability 向量中的第一个值,那么返回 0 就可以了。你明白了吗?
  • 然后查看已编辑的解决方案。我想我现在明白了。
【解决方案2】:

您正在尝试按区间对连续值(在 random 中)进行分类,区间由 demand.probability 给出,并且应该标记为 demand.variation 中给出的值。 这可以通过 R 中的 cut() 函数来完成。 但是,您必须添加一些额外的边框(-Inf、Inf 和例如值 0)。

只需将您的 for-loop 大表达式替换为:

result[, 2] <- cut(random, breaks=c(-Inf, demand.probability, Inf), labels=c(0, demand.variation))

您可以将其作为一个函数来执行(带有可重复性的种子):

categorize_months <- function(n_months, breaks, labels, seed=42) {
  set.seed(seed)
  random <- runif(n_months, 0, 1)
  months <- 1:n_months
  demands <- cut(random, breaks=c(-Inf, breaks, Inf), labels=c(0, labels))
  df <- data.frame("Month"=months, "Demand"=demands)
  df
}

categorize_months(25, demand.probability, demand.variation, seed=42)

【讨论】:

  • 感谢您的回答。我会检查一下,我会在一分钟内回来。
  • 不客气!请注意 - random 的值每次都会改变,因为您没有在 R 中放置 seed 来控制随机数生成器。
  • 所以用于控制 - 运行你的 for 循环并与 cut() 表达式的值进行比较。
  • 嗨,我回来了。所以我尝试了你的代码,它非常接近解决我的问题。您的代码确实对我的 demand.probability 数据进行了分类,但它没有从 demand.variation 返回值,而是返回了一个介于 1 到 6 之间的数字,我相信它是类间隔索引。它没有用 demand.variation 数据标记每个类。真的很近
  • 如果我能做些什么来自动标记每个类别,请随时通知我。现在我可以手动将索引与我的 demand.variation 数据链接起来。感谢您的帮助!
猜你喜欢
  • 2021-04-08
  • 1970-01-01
  • 1970-01-01
  • 2021-06-06
  • 1970-01-01
  • 2020-09-25
  • 2020-03-01
  • 2019-12-27
  • 1970-01-01
相关资源
最近更新 更多