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

时间:2015-02-24 15:45:01

标签: r if-statement

问题

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

我编写了很多if的函数,但它返回警告the condition has length > 1 and only the first element will be used。经过一段时间的研究后,我发现R中的if被设计为使用一个表达式来计算单个布尔值,而ifelse可以使用向量。

但是因为大约有10个链else if s ifelse s同样的东西会相当难看。

实施例

if s:

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

ifelse s

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

问题

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

2 个答案:

答案 0 :(得分:3)

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]

答案 1 :(得分:1)

如您所述,您的函数仅适用于单个值,因为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)

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