R - 如果是多个条件,则为矢量化

时间:2017-05-09 18:33:30

标签: r if-statement conditional-statements

我正在尝试根据以下表达式计算取决于三个不同温度的热应力指数:

enter image description here

我的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

但是,如果我尝试计算hsa范围Teff,请执行以下操作:

Teff=seq(30,40,1)

我收到以下警告:

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

这显然是因为if()没有矢量化,因此只评估矢量的第一个元素。

我了解了ifelse(),它是矢量化的if(),但我不确定它如何用于多种条件。

所以,我的问题是:使用向量而不是标量计算我的hsa索引的替代矢量化方法是什么?

3 个答案:

答案 0 :(得分:2)

这个怎么样?

它与上面的功能相同,但没有明确的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

**请注意,您最后可以添加+ 0*(Teff>=Tlim),但不会更改任何内容,因为无论如何分配的值都是0。

如果你真的想使用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

答案 1 :(得分:1)

正确思考这类问题的方法是考虑&#34;逻辑索引&#34;。

Example

答案 2 :(得分:1)

@kandel是对的。更好的方法是使用逻辑索引。

定义逻辑条件

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

在您的示例中,以下

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

会转换为

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