I am working inside a loop where I will need to replicate a character string a certain number of times. As I progress through the loop, the amount of times it is replicated needs to increase, and I'm pulling that value from a vector. My loop gets stuck on the iteration where "ES" needs to be replicated 56 times, because the rep() function only replicates it 55 times. This is part of a larger task, but I've stripped it down to just the part that is failing.
In troubleshooting this, I've found that it only occurs when the number of times I need "ES" replicated is referenced from a vector of percentages. If I specify x as the value itself, it works fine, and produces the full 56-length vector. But when pulling x from the sequence, it only produces a 55-length vector.
# This produces a 56-length vector
x <- 0.14
y <- 400
test <- rep("ES",times=x*y)
length(test)
class(x)
# This produces a 55-length vector
x <- seq(0.02,0.50,0.02)[7]
y <- 400
rep("ES",times=x*y)
length(test)
class(x)
Variable x is of class "numeric" in both instances. After a lot of testing, the only thing I can find that works is converting x to a character and then converting it back to a number again.
i <- seq(0.02,0.50,0.02)
x <- as.character(i[7])
x <- as.numeric(x)
y <- 400
rep("ES",times=x*y)
Can anyone explain why this is happening?
This is R, for the benefit of people who don't guess.
The problem is that x*y is not a whole number, because floating point arithmetic is not exact. The help page (?rep) says about the times argument
an integer-valued vector giving the (non-negative) number of times to repeat each element if of length length(x), or to repeat the whole vector if of length 1. Negative or NA values are an error. A double vector is accepted, other inputs being coerced to an integer or double vector.
and we see that
> x <- seq(0.02,0.50,0.02)[7]
> y <- 400
> x*y
[1] 56
> x*y-56
[1] -7.105427e-15
> as.integer(x*y)
[1] 55
So: 55.
Things that would do what you wanted:
rep("ES", times=round(x*y))
or using integers in the seq if you know everything is an integer multiple
> i<-seq(1, 25)
> x <- as.character(i[7])
> x <- as.numeric(x)
> y <- 400
> as.integer(x*y/50)
[1] 56
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With