编写嵌套 for 循环,其中语句在 R 中具有多个条件

Writing for nested for loop where statements have multiple conditions in R

我正在尝试根据篮球场的某些区域确定投篮命中率,包括禁区、油漆区(不包括禁区)、所有其他 2 个三分球、底角 3 分球和所有其他区域3 个。

我拥有的是结果(命中或未命中)或每次击球的 x、y 坐标。我试图做的是编写一个 for 循环来获取行和行信息,并使用嵌套的 ifelse 语句检查是否满足多个条件。

for (i in cs){shotarea[i] <- ifelse(x[i] >= -125 & x[i] <= 125 & y[i] < x[i]*tan(acos(x[i]/125)),1,
                  ifelse(x[i] => -125 & x[i] <= 125 & y[i] < 460 & y[i] > 460-x[i]*tan(acos(x[i]/125)),2,
                  ifelse(x[i] >= -245 & x[i] < -125 & y[i] < 460,2,
                  ifelse(x[i] <= 245 & x[i] > 125 & y[i] < 460,2,
                  ifelse(x[i] >= -660 & x[i] < -245 & y[i] < x[i]*tan(acos(x[i]/675)),3,
                  ifelse(x[i] > -245 & x[i] < 245 & y[i] < x[i]*tan(acos(x[i]/675)) & y > 460,3,
                  ifelse(x[i] > 245 & x[i] <= 660 & y[i] < x[i]*tan(acos(x[i]/675)),3,
                  ifelse(x[i] > -750 & x[i] < -660 & y[i] < x[i]*tan(acos(660/675)),4,
                  ifelse(x[i] < 750 & x[i] > 660 & y[i] < x[i]*tan(acos(660/675)),4,
                  ifelse(x[i] > -750 & x[i] < -660 & y[i] > x[i]*tan(acos(660/675)),5,
                  ifelse(x[i] < 750 & x[i] > 660 & y[i] > x[i]*tan(acos(660/675)),5,
                  ifelse(x[i] > -660 & x[i] < 660 & y[i] > x[i]*tan(acos(x[i]/675)),5,6))))))))))))}

我用几何函数对球场上的所有区域进行了界定:
禁区 = x(-125,125), y(inf, xtanacos(x/125))

油漆,不包括禁区= (x(-245,-125)U(125,245), y(inf, 460)) and (x(-125,125),y(xtanacos(x/125),460))

所有其他 2 = (x(-660,-245)U(245,660),y(inf, x[i]tanacos(x[i]/675 )) 和 (x(-245,245),y(460,x[i]tanacos(x[i]/675))

底角 3's = x(-750,-660)U(660,750),y(inf,x[i]tanacos(660/675)

所有其他 3 = (x(-750,-660)U)(660,750),y(x[i]tanacos(660/675),inf) ) 和 (x(-660,660),y(x[i]tanacos(x[i]/675),inf)

x值的范围是(-750,750),y值的范围是(-87,972),其中(0,0)是篮子的中心,x值的范围是边线到边线。根据 x 值的范围,我 运行 有几个数据子集。我 运行 一个子集,其中 x 范围为 (-125,125),一个子集 运行s (-675,-125)U(125,675),另一个子集 (-750,-675)U( 675,750)。 (我这样做是为了防止 arccos() 表达式返回 NAN 作为预防措施,但我认为我实际上不需要这样做)。您还会注意到我对 i 的范围使用了一个向量,这样我就可以分出我制作的不同子集。不确定是否是这个问题。

每当我尝试 运行 它时,我得到

Error: unexpected ')' in:"ifelse((x[i] < 750 && x[i] > 660 && y[i] > x[i]*tan*acos(660/675)),5,
                  ifelse((x[i] > -660 && x[i] < 660 && y[i] > x[i]*tan*acos(x[i]/675)),5,6)))))))))))", > }Error: unexpected '}' in "}"

我仔细检查并三次检查以确保我没有放入多余的括号或方括号,但我找不到。所以我想我要的是两件事之一:

代码是否有其他问题可能导致此错误?

AND/OR

你能推荐更好的吗?我敢肯定肯定有一些 "apply" 方法可以做到,但我对申请很犹豫,不知道从哪里开始。

EDIT: For sample data, you could use x <- runif(3580,min=-749,max=749); y <- runif(3580,min=-86,max=971)

EDIT: I went through and made sure the tan() functions had parenthesis, but otherwise removed what I hope are redundant parethenses

您可以使用 dplyrcase_when 函数更简单地完成此操作。这种方法完成了两件事。首先,它消除了 for 循环,从而减少了评估时间。其次,它不使用所有 ifelse 语句。

library(dplyr)
x <- runif(3580,min=-749,max=749); y <- runif(3580,min=-86,max=971)
df <- data.frame(x = x, y = y)
df1 <- df %>%
  mutate(shotarea = case_when(.$x >= -125 & .$x <= 125 & .$y < .$x*tan(acos(.$x/125)) ~ "restricted",
                              .$x >= -125 & .$x <= 125 & .$y < 460 & .$y > 460-.$x*tan(acos(.$x/125)) ~ "paint",
                              ((.$x >= -245 & .$x < -125) | (.$x > 125 & .$x <= 245)) & .$y < 460 ~ "paint",
                              .$x > -245 & .$x < 245 & .$y < .$x*tan(acos(.$x/675)) & .$y > 460 ~ "other 2",
                              ((.$x >= -660 & .$x < -245) | (.$x > 245 & .$x <= 660)) & .$y < .$x*tan(acos(.$x/675)) ~ "other 2",
                              ((.$x >= -750 & .$x < -660) | (.$x > 660 & .$x <= 750)) & .$y < .$x*tan(acos(660/675)) ~ "corner 3",
                              ((.$x >= -750 & .$x < -660) | (.$x > 660 & .$x <= 750)) & .$y > .$x*tan(acos(660/675)) ~ "other 3",
                              .$x > -660 & .$x < 660 & .$y > .$x*tan(acos(.$x/675)) ~ "other 3",
                              TRUE ~ "other"))

你的输出将是:

> head(df1)
           x         y shotarea
1 -719.26311 733.67983  other 3
2  294.60845 574.06028  other 2
3  423.09931  62.15332  other 2
4  597.60403 960.28765  other 3
5 -592.23907 486.24250  other 3
6   33.58853 411.12968    paint

现在,我使用了实际名称而不是 1-6 编号系统,因为我认为这使得数据可视化和解释对于其他人以及未来的你来说容易得多。但是您可以使用此设置轻松将其更改回 1-6 系统(6 是 "other")

好吧,我发现了我的问题,而且它非常愚蠢。

在第二个ifelse() 语句中,条件x[i] => -125 中运算符的语法被切换,应该是x[i] >= -125。前导 = 弄乱了所有内容的读取方式,这让 R 认为后面的圆括号和方括号是出乎意料的。将两个向后翻转解决了问题。

不过,我很感激任何其他回复给我的想法看起来更清晰。我知道一个很大的嵌套 ifelse() 语句,里面有很多 & 条件语句,看起来一点也不漂亮,而且写起来很烦人。我肯定会改用 tbradley 的 dplyr 解决方案。