【问题标题】:If-else chain not returning correct results in R?If-else 链在 R 中没有返回正确的结果?
【发布时间】:2020-05-09 13:42:04
【问题描述】:

所以我最近开始真正深入研究不同的函数类型,目前正在研究一个接收赛前信息的函数,例如(比赛时间、主场、客场、投注赔率)将这些信息插入到预测模型中,然后最后输出预测。但是我无法在原始 for 循环中获取 if-else 语句链来输出我想要的正确句子。

这是函数的结构。我取出了实际模型并为这个问题制造了结果。该模型是在函数外部创建的,并使用 car::predict 函数

library(dplyr)
library(sjmisc)
#Here is an example of a data set that would be input into the function
x <- data.frame(home= c("CLE","MIL","DET"),away= c("BOS","IND","OKC"),O_U= c(215.5, 220.5, 209.5),linea= c("+","-","+"),lineb= c(4.0,11.0,8.5),gt= c("2020-02-20 19:00:00","2020-02-20 19:00:00","2020-02-20 19:00:00"))


predictor <- function(x){


gametime <- x[,6]
q <- x[,1] 
w <- x[,2]
OvUn <- x[,3]
linefavor <- x[,4]
spreadtot <- x[,5]


#I took the model out from here and just appended the results onto the end of the x dataframe. The model reproduced this exact table
y <- data.frame(HScore=c(105,114,105),AScore=c(117,106,110))
x <- cbind.data.frame(x,y)

# Here I put them in categories based off of the predictions(1 is true,0 is false,3 is Push)
x <- mutate(x, homewin = ifelse(HScore>AScore,1,0)) 
x <- mutate(x, underdog = ifelse(linefavor == "+",1, ifelse(linefavor == "-",0,"NA")))
x <- mutate(x, Over = ifelse(round(HScore)+round(AScore) > OvUn,1, ifelse(round(HScore)+round(AScore) < OvUn,0,3)))

x <- mutate(x,homecover = ifelse((underdog==1 & (round(HScore)+spreadtot)-round(AScore)>0) | (underdog==0 & (round(HScore)-spreadtot)-round(AScore)>0),1,
                                 ifelse((underdog==1 & (round(HScore)+spreadtot)-round(AScore)==0 | (underdog==0 & (round(HScore)-spreadtot)-round(AScore)==0)),3,0)))

print(x)

#Here is where my results become inaccurate. 
if(homewin ==1 & Over ==1 & homecover ==1){
  return(paste0(w," v ",q,": ",q," win ", round(x$HScore),"-",round(x$AScore),", ",q," cover ",linefavor,spreadtot," spread", " Over ",OvUn))
} else if(homewin ==1 & Over ==1 & homecover ==0){
  return(paste0(w," v ",q,": ",q," win ", round(x$HScore),"-",round(x$AScore),", ",w," cover ",linefavor2,spreadtot," spread", " Over ",OvUn))
} else if(homewin ==1 & Over ==0 & homecover ==0){
  return(paste0(w," v ",q,": ",q," win ", round(x$HScore),"-",round(x$AScore),", ",w," cover ",linefavor2,spreadtot," spread", " Under ",OvUn))
} else if(homewin ==1 & Over ==0 & homecover ==1){
  return(paste0(w," v ",q,": ",q," win ", round(x$HScore),"-",round(x$AScore),", ",q," cover ",linefavor,spreadtot," spread", " Under ",OvUn))
} else if(homewin ==0 & Over ==1 & homecover ==1){
  return(paste0(w," v ",q,": ",w," win ", round(x$AScore),"-",round(x$HScore),", ",q," cover ",linefavor,spreadtot," spread", " Over ",OvUn))
} else if(homewin ==0 & Over ==1 & homecover ==0){
  return(paste0(w," v ",q,": ",w," win ", round(x$AScore),"-",round(x$HScore),", ",w," cover ",linefavor2,spreadtot," spread", " Over ",OvUn))
} else if(homewin ==0 & Over ==0 & homecover ==0){
  return(paste0(w," v ",q,": ",w," win ", round(x$AScore),"-",round(x$HScore),", ",w," cover ",linefavor2,spreadtot," spread", " Under ",OvUn))
} else if(homewin ==0 & Over ==0 & homecover ==1){
  return(paste0(w," v ",q,": ",w," win ", round(x$AScore),"-",round(x$HScore),", ",q," cover ",linefavor,spreadtot," spread", " Under ",OvUn))


} else{
  return("ERROR")
}

  }

#Here is what my result looks like
predictor(x)
#Here is what it should look like
accurate <- c("BOS v CLE: BOS win 117-105, BOS cover -4 spread, Over 215.5","IND v MIL: MIL win 114-106, MIL cover -11 spread, Under 220.5","OKC v DET: OKC win 110-105, DET cover +8.5 spread, Over 209.5")
accurate

过去几天我一直在试图找出问题的根源。

【问题讨论】:

  • 如果我可以温和地说,问题之一是您的代码格式不正确。我认为您正在尝试强制 R 手动执行操作(例如,使用 if else 逻辑)它可能会非常简单地执行操作。例如,考虑在代码开头使用data.frame 函数(例如,注意运行data.frame(x=c(1,2,3), y = c("a", "b", "c")) 时会发生什么。)此外,您的for 循环没有做任何事情;您可以删除 for (i in example_x) 并在 example_x 中得到相同的结果。发布一个起始数据和期望结果的示例,我们也许可以提供帮助。
  • @GeoffreyPoole 没有冒犯。批评很有帮助。我重新格式化了这个问题,这样它就可以重现并且更容易浏览。希望这可以解决我的问题。

标签: r for-loop if-statement predict


【解决方案1】:

您可能想在 Google 中搜索 R 中的“向量运算”。这是一种不同的思维方式,也是 R 中的默认思维方式。你不能用它解决所有问题,所以 R 仍然有 @ 987654321@ 循环,但您想尽量避免它们。

我对体育博彩了解的不够深入,无法确定谁覆盖或不覆盖什么点差以及高/低的东西,但我可以让您开始使用更简单的方法。

首先,使用$ 运算符将data.frame 中的列作为向量引用。这样,您不必将列分配给不同的变量,并且您的代码更具可读性。作为x$home 的替代品,您还可以使用x[[1]]x[["home"]]。 (请注意,x["home"] -- 单括号 -- 返回单列 data.frame 而不是向量。)我喜欢使用列名而不是列号,因此如果列的顺序发生更改,我的代码仍然有效在未来。

使用您示例中的x data.frame,我将通过构建应位于所需输出的每个位置的字符向量来解决此问题。例如。

winningTeam = ifelse(df$HScore > df$AScore, as.character(df$home), as.character(df$away))
winScore = pmax(x$HScore, x$AScore)
loseScore = pmin(x$HScore, x$AScore)

产量:

> winningTeam
[1] "BOS" "MIL" "OKC"
> winScore
[1] 117 114 110
> loseScore
[1] 105 106 105

您可以使用相同的通用方法来创建覆盖价差、覆盖多少、失败者等的向量。

那么,因为paste 函数处理向量,所以只需paste 将向量放在一起:

result = paste0(x$home, " v ", x$away, ": ", winningTeam, " win ", winScore, "-", loseScore)

结果是:

> result
[1] "CLE v BOS: BOS win 117-105" "MIL v IND: MIL win 114-106" "DET v OKC: OKC win 110-105"

【讨论】:

  • 很好的答案和解释。我要补充一点,对于“填充空白”字符串构造,我发现sprintfglue::glue 通常比paste 更具可读性。这就像glue::glue_data(x, '{home} v {away}: {winningTeam} win {winScore}-{loseScore}'),读起来非常好。 (paste 非常适合 2 或 3 个字符串,或者它是 collapse 参数。)
  • 谢谢,这很有帮助
猜你喜欢
  • 2020-04-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-14
  • 2014-09-13
  • 2012-08-01
  • 2014-05-10
  • 1970-01-01
相关资源
最近更新 更多