替代 R 中嵌套的 ifelse() 语句

Alternative to nested ifelse() statements in R

问题

我需要一个函数来计算仪器在不同范围内的测量不确定度(例如,我测量电流,如果它在 2 mA 的范围内,则不确定度是测量值的 0.1 % + 3 dig)。如果函数能够接受一个向量和 return 一个向量而不只是数字,那就更好了。

我编写的函数有很多 if,但它 return 有警告 the condition has length > 1 and only the first element will be used。经过一段时间的研究,我发现 R 中的 ifs 设计用于处理计算结果为单个布尔值的表达式,而 ifelse 可以处理向量。

但是因为有大约十个链式 else ifs 与 ifelses 相同的东西会相当难看。

例子

ifs:

S.I = function(I) {
   if(I<=(2*10^(-6))){
      0.1*I/100 + 3*10^(-9)
   } else if(I<=(20*10^(-6))) {
      ...
   }
   ...
}

ifelses

S.I = function(I) {
   ifelse(I<=(2*10^(-6)),0.1*I/100 + 3*10^(-9),ifelse(I<=(2*10^(-6)),...,ifelse(...)))
}

问题

在这种情况下,是否有 ifelses 的替代方案?

如您所述,您的函数仅适用于单个值,因为 if 不适用于向量。解决方案是将向量的每个值一一发送给函数。

R 提供了一组 apply 函数来执行此操作(类似于 for 循环但速度更快):

result = sapply(I_vector, S.I)

如果您想在向量代码中多次应用 S.I,使用包装器是值得的:

wrapper_S.I = function(I) { return(sapply(I_vector, S.I)) }
result = wrapper_S.I(I_vector)

注意: 您还可以使用 Vectorize 创建包装器:

wrapper_S.I = Vectorize(S.I)

创建一个带有额外控件的包装器。

R中通常的做法可能是cut;这是一个例子。

## some sample current values
I <- c(1e-6, 2e-6, 1e-5, 2e-5, 1e-4, 2e-4, 1e-3, 2e-3)
## define the endpoints for the different ranges
breaks <- c(-Inf, 2*10^(-6:3))
## for each range, define the percent of the original
## and the amount to add
percent <- c(0.10, 0.11, 0.12, 0.13)
dig <- c(3e-9, 3e-8, 3e-7, 3e-6) 
## get the range that each value falls in
range <- cut(I, breaks, labels=FALSE)
## and multiply by the right percent and add the right extra amount
I*percent[range]/100 + dig[range]