解释“if”函数中的“条件长度> 1”警告

Interpreting "condition has length > 1" warning from `if` function

提问人:user1723765 提问时间:1/5/2013 最后编辑:zx8754user1723765 更新时间:12/19/2022 访问量:249561

问:

我有一个数组:

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)

并希望实现以下功能:

w<-function(a){
  if (a>0){
    a/sum(a)
  }
  else 1
}

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

否则,它应该只记录 1。

我收到以下警告消息:

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

如何更正该功能?

r if 语句

评论

0赞 agstudy 1/5/2013
@user1723765你期望得到什么结果呢?
1赞 user1723765 1/5/2013
所以基本上,如果 a[a>0] 那么应该完成 a/sum(a),而不是 a[a>0]/sum(a)
0赞 user1723765 1/5/2013
对于其他数字,结果将是 0s 和 .166667 等,但我最终仍然会得到整个向量
0赞 user1723765 1/5/2013
是的,我刚刚意识到。谢谢!
0赞 Sven Hohenstein 1/5/2013
您的实际向量是否仅包含零和一?

答:

66赞 user1317221_G 1/5/2013 #1

也许你想要: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

评论

5赞 Willem 12/5/2018
警告:如果 else 仅使用解决方案中的元素,因为条件中有元素!它没有对此发出警告。例如,返回 answer 而不是 .ifelse(c(T, T), 1:5, 5:1)' 返回 ,以此类推。请谨慎使用。ifelse(TRUE, 1:5, 5:1)11:5c(1, 2)
57赞 jem77bfp 1/5/2013 #2

if语句未矢量化。对于矢量化的 if 语句,您应该使用 .就您而言,写就足够了ifelse

w <- function(a){
if (any(a>0)){
  a/sum(a)
}
  else 1
}

或简短的矢量化版本

ifelse(a > 0, a/sum(a), 1)

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

评论

20赞 tumultous_rooster 8/18/2015
为什么哦,为什么,如果 R-land 中的其他一切都是矢量化的......“如果”不是?SMDH的。
0赞 Alejandro Carrera 6/14/2022
9 年后,您使用 if(any()) 的解决方案帮助了我。你是个天才。谢谢!
20赞 Sven Hohenstein 1/5/2013 #3

这里有一种简单的方法,没有:ifelse

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

举个例子:

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

评论

6赞 Matthew Lundberg 1/5/2013
这大约是 7 倍(在 100000 个元素数组上)。ifelse
1赞 theforestecologist 11/13/2017
您能否推荐此运算符的简洁解释/文档(例如,它叫什么以及它是如何工作的)。最好是比算术运算符文档更直接的东西......^
5赞 Sven Hohenstein 11/14/2017
@theforestecologist 运算符用于求幂。该命令的意思是:提升到 的幂。该代码将计算 .^x ^ yxy2 ^ 32 * 2 * 2
27赞 Atesh 4/30/2015 #4

只是在整个讨论中添加一个关于为什么会出现此警告的要点(我以前不清楚)。如前所述,之所以得到这个,是因为在这种情况下,“a”是一个向量,而不等式“a>0”产生另一个 TRUE 和 FALSE 向量(其中“a”是 >0 或不是)。

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

最好

3赞 rlhull6 11/13/2017 #5

我遇到这个问题的方式是当我尝试做类似的事情时,我正在定义一个函数,并且像其他人指出的那样用数组调用它

您可以做这样的事情,但是对于这种情况,与 Sven 的方法相比,它不那么优雅。

sapply(a, function(x) afunc(x))

afunc<-function(a){
  if (a>0){
    a/sum(a)
  }
  else 1
}
3赞 masih_MineParisTech_france 3/31/2019 #6

正常创建函数后使用函数。lapply

lapply(x="your input", fun="insert your function name")

lapply给出一个列表,因此使用 function 将它们从函数中删除unlist

unlist(lapply(a,w))

评论

0赞 camille 5/15/2019
你的意思是把它从列表中拿出来,而不是功能吗?unlist
0赞 masih_MineParisTech_france 6/28/2019
是的,我的意思是,对不起,打错了
1赞 Ramya Roopa 12/19/2022 #7

我想说最有效的方法是通过以下方式回答 user1317221_G。但是,如果您想回到基础,那么使用 for 函数遍历向量的长度(因为 if 函数在向量的长度上不起作用)会很有用。

w <- c() ##creates empty vector named 'w'
for(i in 1:length(a)){
  if (a[i]>0){
    w[i] <- a[i]/sum(a)
  }
  else 
    w[i] <- 1
}