Why does sample() not work for a single number? [duplicate] - r

This question already has answers here:
Sample from vector of varying length (including 1)
(4 answers)
Closed 3 years ago.
sample(x,n) The parameters are the vector, and how many times you wish to sample
sample(c(5,9),1) returns either 5 or 9
however,
sample(5,1) returns 1,2,3,4, or 5?
I've read the help section:
If x has length 1, is numeric (in the sense of is.numeric) and x >= 1,
sampling via sample takes place from 1:x. Note that this convenience
feature may lead to undesired behaviour when x is of varying length in
calls such as sample(x). See the examples.
But is there a way to make it not do this? Or do I just need to include an if statement to avoid this.

Or do I just need to include an if statement to avoid this.
Yeah, unfortunately. Something like this:
result = if(length(x) == 1) {x} else {sample(x, ...)}

Here's an alternative approach: you simply subset a random value from your vector like this -
set.seed(4)
x <- c(5,9)
x[sample(length(x), 1)]
[1] 9
x <- 5
x[sample(length(x), 1)]
[1] 5

Related

Muliplying Elements of a Vector one more each time

I am trying to create a vector from another vector where I multiply the numbers in the vector one more each time.
For example if I had (1,2,3) the new vector would be (1, 1 x 2, 1 x 2 x 3)=(1,2,6)
I tried to create a loop for this as seen below. It seems to work for whole numbers but not decimals. I am not sure why.
x <- c(0.99,0.98,0.97,0.96,0.95)
for(i in 1:5){x[i]=prod(x[1:i])}
The result given is 0.9900000 0.9702000 0.9316831 0.8590845 0.7303385
which is incorrect as prod(x) = 0.8582777. Which is not the same as the last element of the vector.
Does anyone know why this is the case? Or have a suggestion for improvement in my code to get the correct answer.
test<-c(1,2,3)
cumprod(test)
[1] 1 2 6
As #akrun suggests, one can achieve the same with:
Reduce("*", test, accumulate = TRUE)

sampling bug in R? [duplicate]

This question already has answers here:
Sample from vector of varying length (including 1)
(4 answers)
Closed 4 years ago.
I am trying to sample one element out of a numeric vector.
When the length of the vector > 1, the result is one of the numbers of the vector, as expected. However when the vector contains one element, it samples a number between 0 and this single number.
For example:
sample(c(100, 1000), 1)
results in either 100 or 1000, however
sample(c(100), 1)
results in different numbers smaller than 100.
What is going on?
Have a look at the Details of the sample function:
"If x has length 1, is numeric (in the sense of is.numeric) and x >= 1, sampling via sample takes place from 1:x"
This is (unfortunately) expected behavior. See ?sample. The first line of the Details section:
If x has length 1, is numeric (in the sense of is.numeric) and x >= 1, sampling via sample takes place from 1:x. Note that this convenience feature may lead to undesired behaviour when x is of varying length in calls such as sample(x). See the examples.
Luckily the Examples section provides a suggested fix:
# sample()'s surprise -- example
x <- 1:10
sample(x[x > 8]) # length 2
sample(x[x > 9]) # oops -- length 10!
sample(x[x > 10]) # length 0
## safer version:
resample <- function(x, ...) x[sample.int(length(x), ...)]
resample(x[x > 8]) # length 2
resample(x[x > 9]) # length 1
resample(x[x > 10]) # length 0
You could, of course, also just use an if statement:
sampled_x = if (length(my_x) == 1) my_x else sample(my_x, size = 1)

R - Equivalent inputs resulting in different outputs for a sequence [duplicate]

This question already has an answer here:
Why does the vector gets expanded in the loop
(1 answer)
Closed 6 years ago.
I am running into some behaviour with R that I find confusing. Does anyone have any insight into what is going on here?
Define two objects
i <- 5
nr <- 10
So i + 2 and nr + 1
> i+2
[1] 7
> nr+1
[1] 11
So to create a sequence from 7 to 11 I could do this:
7:11
But my question why does this not produce the same result?
i+2:nr+1
We already established above that it's input numbers are equivalent. Obviously I'm missing something here but I just don't know what it is.
You have just discovered the prime R gotcha, namely: 1:n-1 produces the sequence 0, 1, 2, ..., n-1.
To obtain what you desire, wrap the expressions in brackets:
1:(n-1)
or use
seq.int(1, n-1)
The reason for the issue is operator precedence - ?Syntax`

counting matching elements of two vectors but not including repeated elements in the count

I've search a lot in this forum. However, I didn't found a similar problem as the one I'm facing.
My question is:
I have two vectors
x <- c(1,1,2,2,3,3,3,4,4,4,6,7,8) and z <- c(1,1,2,4,5,5,5)
I need to count the number of times x or z appears in each other including if they are repeated or not.
The answer for this problem should be 4 because :
There are two number 1, one number 2, and one number 4 in each vector.
Functions like match() don't help since they will return the answer of repeated for non repeated numbers. Using unique() will also alter the final answer from 4 to 3
What I came up with was a loop that every time it found one number in the other, it would remove from the list so it won't be counted again.
The loop works fine for this size of this example; however, searching for larger vectors numerous times makes my loop inefficient and too slow for my purposes.
system.time({
for(n in 1:1000){
x <- c(1,1,2,2,3,3,3,4,4,4,6,7,8)
z <- c(1,1,2,4,5,5,5)
score <- 0
for(s in spectrum){
if(s %in% sequence){
sequence <- sequence[-which(sequence==s)[1]]
score <- score + 1
}
}
}
})
Can someone suggest a better method?
I've tried using lapply, for short vectors it is faster, but it became slower for longer ones..
Use R's vectorization to your advantage here. There's no looping necessary.
You could use a table to look at the frequencies,
table(z[z %in% x])
#
# 1 2 4
# 2 1 1
And then take the sum of the table for the total
sum(table(z[z %in% x]))
# [1] 4

R numbers from 1 to 100 [duplicate]

This question already has an answer here:
Closed 10 years ago.
Possible Duplicate:
How to generate a vector containing a numeric sequence?
In R, how can I get the list of numbers from 1 to 100? Other languages have a function 'range' to do this. R's range does something else entirely.
> range(1,100)
[1] 1 100
Your mistake is looking for range, which gives you the range of a vector, for example:
range(c(10, -5, 100))
gives
-5 100
Instead, look at the : operator to give sequences (with a step size of one):
1:100
or you can use the seq function to have a bit more control. For example,
##Step size of 2
seq(1, 100, by=2)
or
##length.out: desired length of the sequence
seq(1, 100, length.out=5)
If you need the construct for a quick example to play with, use the : operator.
But if you are creating a vector/range of numbers dynamically, then use seq() instead.
Let's say you are creating the vector/range of numbers from a to b with a:b, and you expect it to be an increasing series. Then, if b is evaluated to be less than a, you will get a decreasing sequence but you will never be notified about it, and your program will continue to execute with the wrong kind of input.
In this case, if you use seq(), you can set the sign of the by argument to match the direction of your sequence, and an error will be raised if they do not match. For example,
seq(a, b, -1)
will raise an error for a=2, b=6, because the coder expected a decreasing sequence.

Resources