从`if`函数解释"condition has length> 1"警告

use*_*765 35 r

我有一个数组:

a <- c(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)
Run Code Online (Sandbox Code Playgroud)

并希望实现以下功能:

w<-function(a){
  if (a>0){
    a/sum(a)
  }
  else 1
}
Run Code Online (Sandbox Code Playgroud)

此函数要检查是否存在a大于0的任何值,如果是,则将每个元素除以总和的总和.

否则它应该只记录1.

我收到以下警告消息:

 Warning message:
 In if (a > 0) { :
 the condition has length > 1 and only the first element will be used
Run Code Online (Sandbox Code Playgroud)

我该如何纠正这个功能?

use*_*1_G 53

也许你想要ifelse:

a <- c(1,1,1,1,0,0,0,0,2,2)
ifelse(a>0,a/sum(a),1)

 [1] 0.125 0.125 0.125 0.125 1.000 1.000 1.000 1.000
 [9] 0.250 0.250
Run Code Online (Sandbox Code Playgroud)

  • 警告:ifelse仅使用解决方案中的尽可能多的元素,因为条件中有多少元素!它不会对此发出警告。例如,“ ifelse(TRUE,1:5,5:1)”将返回“ 1”作为答案,而不是“ 1:5”。ifelse(c(T,T),1:5,5:1)`返回`c(1,2)`,依此类推。请谨慎使用。 (3认同)

jem*_*bfp 39

if声明没有矢量化.对于你应该使用的矢量化if语句ifelse.在你的情况下,写作就足够了

w <- function(a){
if (any(a>0)){
  a/sum(a)
}
  else 1
}
Run Code Online (Sandbox Code Playgroud)

或简短的矢量化版本

ifelse(a > 0, a/sum(a), 1)
Run Code Online (Sandbox Code Playgroud)

这取决于你想要使用哪个,因为第一个函数给出长度为1的输出向量(在其他部分),并ifelse给出长度等于长度的输出向量a.

  • 为什么哦,为什么,如果R-land中的其他东西都被矢量化了......'如果'不是?Smdh. (14认同)

Sve*_*ein 17

这是一个简单的方法ifelse:

(a/sum(a))^(a>0)
Run Code Online (Sandbox Code Playgroud)

一个例子:

a <- c(0, 1, 0, 0, 1, 1, 0, 1)

(a/sum(a))^(a>0)

[1] 1.00 0.25 1.00 1.00 0.25 0.25 1.00 0.25
Run Code Online (Sandbox Code Playgroud)

  • 这比"ifelse"大约7倍(在100000个元素阵列上). (5认同)
  • @theforestecologist运算符`^`用于取幂.命令`x ^ y`表示:`x`被提升到'y`的幂.代码"2 ^ 3"将计算"2*2*2". (3认同)

小智 14

只是在整个讨论中添加一个观点,说明为什么会出现这个警告(之前我不清楚).之所以如前所述是因为在这种情况下'a'是向量而不等式'a> 0'产生另一个向量为TRUE和FALSE(其中'a'> 0或者不是).

如果你想测试是否有'a> 0'的任何值,你可以使用函数 - 'any'或'all'

最好