42

我有一个数组:

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
}

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

否则它应该只记录 1。

我收到以下警告消息:

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

如何更正该功能?

4

6 回答 6

64

也许你想要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
于 2013-01-05T10:25:47.573 回答
47

if语句未向量化。对于向量化的 if 语句,您应该使用ifelse. 在你的情况下,写就足够了

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

或简短的矢量化版本

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

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

于 2013-01-05T10:29:32.343 回答
22

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

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

最好的

于 2015-04-30T13:56:01.467 回答
20

这是一个没有 的简单方法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
于 2013-01-05T12:42:10.523 回答
3

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

你可以做这样的事情,但是与 Sven 的方法相比,在这种情况下它不太优雅。

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

afunc<-function(a){
  if (a>0){
    a/sum(a)
  }
  else 1
}
于 2017-11-13T00:22:28.743 回答
2

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

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

lapply给出一个列表,所以使用unlist函数将它们从函数中取出

unlist(lapply(a,w))
于 2019-03-31T11:28:17.523 回答