简体   繁体   中英

mysterious values as output in vector R using if and else

I have a vector of values (numbers only). I want to split up this vector into two vectors. One vector will contain values less than the average of the original vector, the other will contain values more than the average of the original vector. I have the following as a test R script:

v <- c(1,1,4,6,3,67,10,194,847)

#Initialize
v.in<- c(rep(0),length(v))
v.out<- c(rep(0),length(v))

for (i in 1:length(v))
{
   if (v < 0.68 * mean(v))
   {
      v.in[i] <- v[i]
   }
   else
   {
      v.out[i] <- v[i]
   }
}
v.in
v.out

## <https://gist.github.com/8a6747ea9b7421161c43>

I get the following result:

9: In if (v < 0.68 * mean(v)) { :
  the condition has length > 1 and only the first element will be used
> v.in
[1]   1   1   4   6   3  67  10 194 847
> v.out
[1] 0 9
> v
[1]   1   1   4   6   3  67  10 194 847
> 

Clearly, 0 and 9 are not values of any of the elements in v.

Any suggestions what is going on and how to fix this?

Thanks, Ed

@BenBolker pointed out in the comment why you code doesn't work: you need to select a single element from v when using if . However, you might find split a better function for a task like this:

split(v,v<0.68*mean(v))
$`FALSE`
[1] 194 847

$`TRUE`
[1]  1  1  4  6  3 67 10

The answer to the mystery of v.out is that its branch doesn't get selected so it doesn't get changed. It therefore retains its inital value, which is (presumably) erroneously given the value of a single 0 and the length of the vector ( 9 ) rather than nine copies of zero as I suspect you intended.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM