How can I randomly change the sign of numbers in a vector? - r

I have a long vector of numbers that vary in the their sign (e.g.):
data <- c(1,-23,67,-21,10,32,64,-34,-6,10)
Working in R, how do I create a new vector that contains the same list of numbers, but give them a random sign (either positive or negative)? For each number, the probability of it being negative should be 0.5.

There are a bunch of options but
sample(c(-1,1), size=length(data), replace=TRUE) * abs(data)
should work. You could also multiply by sign(runif(length(data))-0.5) or sign(runif(length(data),-1,1)) [either of which should be a little more efficient than sample(), although in this case it hardly matters].

Related

Octave: Values inside a matrix that are close

I have a vector that is being filled with random numbers within this range [0,1]. I want to somehow accept only the vectors, in which an element inside of it has a maximum deviation of 0,02 from its previous one and its next one.
For example I have the below vector [3,1]. This is acceptable, because the deviation of the 2nd element, between the first and the third element is not bigger than 0,02. Vector is not always consisted of 3 rows, it could be more.
**Vector**
0.32957
0.33097
0.33946
This is what i thought:
n=4
P=rand(1,n);
sort(P,"ascend");
for L=2:n
while P(L-1)-P(L)>0.02
P=rand(1,n);
endwhile
endfor
Vectorize this!
isvalid=~any(diff(sort(a))>0.02);
sort(a) : if its not sorted, sort
diff() : take the difference between adjacent elements
___ >0.02: Check if any of those differences is bigger than what you accept
~any(): if any is bigger, then return zero, "not valid".
From your code, it seems that there may be more to the question than what you ask, you seem to have the XY problem. You want to create a random vector that has the properties that you describe. You seem to be using uniform random numbers, so let me propose a way to generate your vector where your conditions are always true.
a(1)=rand(1); %or any other way to generate a first value.
length=100; %desired length.
a(2:length)=rand(length-1,1)*0.02; %generate random numbers never bigger than 0.02
a=cumsum(a); %cumulative sum
This ensures the vector is increasing in value, and never increasing more than 0.02

Is there an R function better than I've used?

Question:
"Create a sequence of numbers from 1:10000
and then deduct 10 from every number in the sequence
convert the negative numbers to positive
Round pi to 12 decimal figures"
Solution:
abs(c(1:10000)-10)
round(pi,12)
Is there a better way to solve?
But, how do you convert all the negative numbers in the output to 12-digit pi?
If - as I interpret the question - you want to decrease 1:1000 by 10 for each number in the range, and then replace all negative numbers in this output with 12-digit pi, you should use:
unlist(purrr::map_if(
1:10000-10,
~.x<0,
~round(pi, 12))
)
In this code, the function map_if() (in the purrr package) applies the function "Replace by round(pi, 12)" to all objects in the range meeting the criteria "x<0", leaving the other values unchanged.
Do I interpret your instructions correctly?

Representing closeness among elements of a double vector

I have a double vector:
r = -50 + (50+50)*rand(10,1)
Now i want to ideally have all the numbers in the vector equal upto a tolerance of say 1e-4. I want to represent each r with a scalar say s(r) such that its value gives an idea of the quality of the vector. The vector is high quality if all elements in the vector are equal-like. I can easily run a for loop like
for i=1:10
for j=i+1:10
check equality upto the tolerance
end
end
But even then i cannot figure what computation to do inside the nested for loops to assign a scalar representing the quality . Is there a better way such that given any vector r length n, i can quickly calculate a scalar representing the quality of the vector.
Your double-loop algorithm is somewhat slow, of order O(n**2) where n is the number of dimensions of the vector. Here is a quick way to find the closeness of the vector elements, which can be done in order O(n), just one pass through the elements.
Find the maximum and the minimum of the vector elements. Just use two variables to store the maximum and minimum so far and run once through all the elements. The difference between the maximum and the minimum is called the range of the values, a commonly accepted measure of dispersion of the values. If the values are exactly equal, the range is zero which shows perfect quality. If the range is below 1e-4 then the vector is of acceptable quality. The bigger the range, the worse the equality.
The code is obvious for just about any given language, so I'll leave that to you. If the fact that the range only really considers the two extreme values of the vector bothers you, you could use other measures of variation such as the interquartile range, variance, or standard deviation. But the range seems to best fit what you request.

Identifying most frequent fractional numbers in vector

I have a vector that contains fractional numbers:
a<-c(0.5,0.5,0.3,0.5,0.2)
I would like to determine the most frequent (i.e. majority) number in the vector and return that number.
table(a) doesn't work because it will return the whole table. I want it to return only 0.5.
In case of ties I would like to choose randomly.
I have a function that does this for integers:
function(x){
a<-tabulate(x,nbins=max(x)); b<-which(a==max(a))
if (length(b)>1) {a<-sample(b,1)} else{b}
}
However, this won't work for fractions.
Can someone help?
You can use
names(which.max(table(a)))
If you want the numeric one as in your case, then coerce it to numeric
as.numeric(names(which.max(table(a))))
To randomize the tie case, you can add randomize the table
as.numeric(names(which.max(sample(table(a))))) #note this works only if length(unique(a)) > 1

Make the sum of all the subtractions of a vector elements in R

Hello I am new to R and I can't find the way to do exactly what I want to. I have a vector of x numbers, and what i want to do is order it in increasing order, and then start making subtractions like this (let's say the vecto has 100 numbers for example):
[x(100)-x(99)]+[x(99)-x(98)]+[x(98)-x(97)]+[x(97)-x(96)]+...[x(2)-x(1)]
and then divide all that sum by the number of elements the vector has, in this case 100.
The only thing that I am able to do at the moment is order the vector with:
sort(nameOfTheVector)
Sorry for my bad English.
diff returns suitably lagged and iterated differences. In your case you want the default single lag. sum will return the sum any arguments passed to it, so....
sum(diff(sort(nameOfTheVector))) / length(nameOfTheVector)

Resources