简体   繁体   English

R-在多个条件下进行向量化

[英]R - vectorized if for multiple conditions

I am trying to calculate a heat stress index that depends on three distinct temperatures, following this expression: 我试图按照以下表达式计算取决于三个不同温度的热应力指数:

在此处输入图片说明

My R implementation works OK for single temperature values: 对于单个温度值,我的R实现可以正常工作:

# Set temperatures
Teff=34
Tcr=33
Tlim=40

# Apply conditions
if (Teff < Tcr) {
  hsa = 1
} else if (Teff >= Tcr & Teff < Tlim) {
  hsa = 1 - ((Teff - Tcr)/(Tlim - Tcr))
} else if (Teff >= Tlim) {
  hsa = 0
}

hsa
  [1] 0.8571429

However, if I try to calculate hsa for a range of Teff , like this: 但是,如果我尝试为Teff的范围计算hsa ,如下所示:

Teff=seq(30,40,1)

I get the following warning: 我收到以下警告:

Warning message:
In if (Teff < Tcr) { :
  the condition has length > 1 and only the first element will be used

Which apparently occurs because if() is not vectorized and therefore evaluates only the first element of the vector. 这显然是因为if()没有向量化,因此仅计算向量的第一个元素而发生的。

I learned about ifelse() , which is vectorized if() , but I'm not sure how it can be used for multiple conditions. 我了解了ifelse() ,它是向量化的if() ,但是我不确定如何将其用于多种条件。

So, my question is: what would be an alternative, vectorized way to calculate my hsa index using vectors instead of scalars? 因此,我的问题是:使用向量而不是标量来计算我的hsa索引的另一种向量化方法是什么?

How about this? 这个怎么样?

It's the same function as above, but without the explicit if and else ? 与上面的功能相同,但是没有明确的ifelse

> Teff=seq(30,40,1)
> hsa<- 1*(Teff<Tcr) + (1 - (Teff - Tcr)/(Tlim - Tcr))*(Teff >= Tcr & Teff < Tlim)
> hsa
 [1] 1.0000000 1.0000000 1.0000000 1.0000000 0.8571429 0.7142857 0.5714286 0.4285714 0.2857143 0.1428571 0.0000000

** Note that you can add + 0*(Teff>=Tlim) in the end, but it wouldn't change anything, because the assigned value would be 0 anyways. **请注意,您可以在最后加上+ 0*(Teff>=Tlim) ,但不会有任何改变,因为分配的值始终为0。

If you really want to use ifelse , then you have to nest them, so it should be something like this: 如果您真的想使用ifelse ,那么您必须将它们嵌套,因此应该是这样的:

> hsa<- ifelse(Teff<Tcr, 1,
               ifelse(Teff >= Tcr & Teff < Tlim, 
               (1 - (Teff - Tcr)/(Tlim - Tcr)), 0))
> hsa
     [1] 1.0000000 1.0000000 1.0000000 1.0000000 0.8571429 0.7142857 0.5714286 0.4285714 0.2857143 0.1428571 0.0000000

Correct way to think about this kind of problem is to think about "logical indexing". 解决此类问题的正确方法是考虑“逻辑索引”。

Example

@kandel is right. @kandel是正确的。 The better way is to use logical indexing. 更好的方法是使用逻辑索引。

Define the logical condition 定义逻辑条件

idx <- iris$Species == "setosa"
new_iris = iris[idx,]

In your example, the following 在您的示例中,以下内容

if (Teff < Tcr) {
  hsa = 1
} else if (Teff >= Tcr & Teff < Tlim) {
         hsa = 1 - ((Teff - Tcr)/(Tlim - Tcr))
       } else if (Teff >= Tlim) {
hsa = 0
}

would translate to 将转化为

idx <- Teff< Tcr
hsa[idx] <- 1 # and so on so forth

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM