我有一个数组:
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
如何更正功能?
答案 0 :(得分:50)
也许你想要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
答案 1 :(得分:37)
if
语句未向量化。对于vectorized if语句,您应该使用ifelse
。在你的情况下,写
w <- function(a){
if (any(a>0)){
a/sum(a)
}
else 1
}
或简短的矢量化版本
ifelse(a > 0, a/sum(a), 1)
这取决于你想要使用哪个,因为第一个函数给出长度为1的输出向量(在其他部分),ifelse
给出长度等于a
长度的输出向量。
答案 2 :(得分:16)
这是一种没有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
答案 3 :(得分:13)
只是在整个讨论中添加一个观点,说明为什么会出现此警告(之前我不清楚)。之前提到的原因是因为在这种情况下'a'是向量而不等式'a&gt; 0'产生另一个TRUE和FALSE向量(其中'a'是> 0或不是)。
如果您想测试是否有'a&gt; 0'的任何值,您可以使用函数 - 'any'或'all'
最佳
答案 4 :(得分:2)
我解决这个问题的方式是当我尝试做类似的事情时,我在定义一个函数,并且像其他人指出的那样用数组调用
你可以做这样的事情但是对于这种情况来说,与Sven的方法相比它不那么优雅。
sapply(a, function(x) afunc(x))
afunc<-function(a){
if (a>0){
a/sum(a)
}
else 1
}
答案 5 :(得分:1)
正常创建函数后,请使用lapply
函数。
lapply(x="your input", fun="insert your function name")
lapply
给出了一个列表,因此请使用unlist
函数将其从函数中删除
unlist(lapply(a,w))