Recode variable based on distance to fixed value in R - distance

I hope you can help me with what seems to be an easy problem but I cannot figure it out.
I have a variable (a) in a dataframe that ranges from 0-10 with continous values. I now want to recode this variable into a new variable where all values correspond to their distance from a fixed value = 5.
In an example, I would like for a to be recoded to the values of b.
a= c(1,2,3,4.5,6,7,9,10,3.4,5.5,7.3)
b= 4.0 3.0 2.0 0.5 1.0 2.0 4.0 5.0 1.6 0.5 1.3
I appreciate any help. Thank you!

Related

Alternate approach for pdist() from scipy in Julia?

My objective is to replicate the functionality of pdist() from SciPy in Julia.
I tried using Distances.jl package to perform pairwise computation of distance between observations. However, the results are not same as seen in the below mentioned example.
Python Example:
from scipy.spatial.distance import pdist
a = [[1,2], [3,4], [5,6], [7,8]]
b = pdist(a)
print(b)
output --> array([2.82842712, 5.65685425, 8.48528137, 2.82842712, 5.65685425, 2.82842712])
Julia Example:
using Distances
a = [1 2; 3 4; 5 6; 7 8]
dist_function(x) = pairwise(Euclidean(), x, dims = 1)
dist_function(a)
output -->
4×4 Array{Float64,2}:
0.0 2.82843 5.65685 8.48528
2.82843 0.0 2.82843 5.65685
5.65685 2.82843 0.0 2.82843
8.48528 5.65685 2.82843 0.0
With reference to above examples:
Is pdist() from SciPy in python has metric value set to Euclidean() by default?
How may I approach this problem, to replicate the results in Julia?
Please suggest a solution to resolve this problem.
Documentation reference for pdist() :--> https://docs.scipy.org/doc/scipy/reference/generated/scipy.spatial.distance.pdist.html
Thanks in advance!!
According to the documentation page you linked, to get the same form as Julia from python (yes, I know, this is the reverse of your question), you can pass it to squareform. I.e. in your example, add
from scipy.spatial.distance import squareform
squareform(b)
Also, yes, from the same documentation page, you can see that the 'metric' parameter defaults to 'euclidean' if not explictly defined.
For the reverse situation, simply note that the python vector is simply all the elements in the off-diagonal (since for a 'proper' distance metric, the resulting distance matrix is symmetric).
So you can simply collect all the elements from the off-diagonal into a vector.
For (1), the answer is yes as per the documentation you linked, which says at the top
scipy.spatial.distance.pdist(X, metric='euclidean', *args, **kwargs)
indicating that the metric arg is indeed set to 'euclidean' by default.
I'm not sure I understand your second question - the results are the same? The only difference to me seems to be that scipy returns the upper triangular as a vector, so if it's just about doing this have a look at: https://discourse.julialang.org/t/vector-of-upper-triangle/7764

unity Mathf.PerlinNoise not between 0 and 1

Does anybody know why this:
Debug.Log(Mathf.PerlinNoise(190911.45f, 2290937.40f));
gives me: 1.044323 It should have been between 0 and 1 isn't it?
And if it can get bigger than 1 can it get smaller than 0? I'm making a map with sprites and everything works :) except that i get empty spaces if the value is bigger than 1.
I use a random seed, that's why the numbers are so big, if you wondering.
I hope someone can help me out, Thanks :)
From the Unity Documentation,
Note: It is possible for the return value to slightly exceed 1.0f. You may need to clamp the return value if the 0.0 to 1.0 range is important to you.
So you need to use float normalized = Mathf.Clamp(Mathf.PerlinNoise(190911.45f, 2290937.40f),0,1f)
Where second argument is minimum value while third argument is maximum value.

How to select the indices of a price series where there is a difference of x bips?

I have a price series and I'd like to know the indices where there has been a change of x bips. I worked out a very ugly way to accomplish this in a loop e.g.
q)bips:200
q)level:0.001*bips / 0.2
q)price: 1.0 1.1 1.3 1.8 1.9 2.0 2.3
q)ix:0
q)lastix:0
q)result:enlist lastix
q)do[count price;if[abs(price[ix]-price[lastix])>level;result,:ix;lastix:ix];ix:ix+1];
q)result
0 2 3 6
This is a simple O(n) algo that walks through the price series and keeps a marked index (lastix) starts from the first element until it finds a price whose difference is greater than bips when found saves that index and updates lastix with the one found ... is there a more idiomatic way to do it?
My if condition inside the loop is somewhat flawed don't know exactly why if I check abs(price[lastix]-price[ix]) instead of abs(price[ix]-price[lastix]) it doesn't give correct results.
UPDATE: I was aware of deltasbut it compares consecutive elements only and that's not what I need in my OP. I apologize if the price series example in the OP was ambiguous and lead to correct results by simply using deltas. Here I have a counter example new prices series:
q)price: 1.0 1.1 1.21 1.42 1.4 1.32 1.63
q)where abs deltas price > level
,0
and this is not correct. The correct result which is produced by the accepted answer is still
0 2 3 6
I think you're looking for something like this maybe:
f:{where differ{$[level<abs[y-x];y;x]}\[x]}
this carries forward the last value that satisfied your condition and uses if for comparison with the scan adverb, and then uses differ to pick out where the condition was satisfied and values were updated.
If I've understood your problem correctly, the same result should come from
newprice:1 1.1 1.3 1.8 1.9 2 2.1
since the final value is more than 0.2 greater than 1.8, the last value at which the level was updated.
q)f newprice
0 2 3 6
Thanks,
Ryan
I'm not sure if this is exactly what you're looking for but deltas will give you the change between consectutive pairs:
q)deltas price
1 0.1 0.2 0.5 0.1 0.1 0.3
Checking for your condition returns a boolean list:
q)level<=deltas price
1011001b
Finally 'where' will return the indices:
q)where level<=deltas price
0 2 3 6
Thanks,
Jamie
level:0.001*bips:200;
result:where level<=abs deltas price:1.0 1.1 1.3 1.8 1.9 2.0 2.3;
result
0 2 3 6
Is this close to what you're looking for?
Deltas checks the difference between the current and next value, abs will take the absolute value, and then you're comparing each difference against "level", which you have predefine, using where to find the associated indice.
You've included index 0 in your answer but if you want to exclude it you can use the two argument form of deltas:
q)where level<=abs deltas[price 0;price]
2 3 6
Where the first argument sets the initial value to take away, in this case the first element of the price list.
An example of where this may be beneficial is if you were running the function for each date in a partitioned db you could pass in the last value from the previous day to ensure you didn't get the indices where there wasn't a significant difference of bips.

Matlab: non-linear-regression, 2 criteria

I am trying to fit a non-linear model using 3 independent variables (light, temperature and vapor pressure deficit (VPD)) to predict net ecosystem CO2 exchange (NEE).
I know how to use the nlinfit function, but my problem is that I want to use 2 criteria:-
1. if VPD < 1.3
NEE = (Param(1).*Param(2).*Ind_var(:,1))./(Param(1).*Ind_var(:,1)+Param(2)) + Param(3).*(1.6324.^((Ind_var(:,2)-18)./10));
2. if VPD >= 1.3
NEE = (Param(1).*(Param(2).*exp(-Param(4).*(Ind_var(:,3)-1.3))).*Ind_var(:,1))./(Param(1).*Ind_var(:,1)+(Param(2).*exp(-Param(4).*(Ind_var(:,3)-1.3))))+Param(3).*(1.6324.^((Ind_var(:,2)-18)./10));
Basically, if the independent variable VPD (Vapor pressure deficit) is below 1.3, I want to force my Param(4) = 0.
But I don't know how to do that.
Could you help me?
Thanks,
Alexis
You can replace Param(4) by Param(4)*(VPD<1.3).
Conditional expressions are evaluated to 1 if true and 0 if false in Matlab.

How do you create a floating point array in MATLAB?

I'm trying to create a 10 x 8 array in MATLAB filled with floating-point values.
Ideas?
UPDATE:
I am actually trying to create an empty 10 x 8 float-type array. How can I do that?
You might want to have a look at the zeros function. To create a 10 x 8 matrix containing all zeros, use
matrix = zeros(10, 8);
To force the elements to be of a certain type (e.g. single precision), use the additional class argument like
matrix = zeros(10, 8, 'single');
(I think, the default is double precision)
matrix = single(rand(10,8));
float is a single in Matlab
rand(10,8); returns a matrix of dimension 10x8 formatted as doubles...you can cast the return value to single(rand(10,8)) to get floating point values...if for some reason you need to have floating point precision instead of double floating point procision
UPDATE: the clarification from the OP made this answer outdated.
If you just want to create a matrix with specific values, here is a one-liner approach:
data = [0. 0.1 0.2 3. 4. 5. 6. 7. 8. 0.9;0. 0.1 0.2 3. 4. 5. 6. 7. 8. 0.9; ...; 0. 0.1 0.2 3. 4. 5. 6. 7. 8. 0.9]
multi-liner approach (if you are about to copy-paste data):
data = [
0. 0.1 0.2 3. 4. 5. 6. 7. 8. 0.9
0. 0.1 0.2 3. 4. 5. 6. 7. 8. 0.9
0. 0.1 0.2 3. 4. 5. 6. 7. 8. 0.9
0. 0.1 0.2 3. 4. 5. 6. 7. 8. 0.9
...
0. 0.1 0.2 3. 4. 5. 6. 7. 8. 0.9
]
However, as many wrote rand(10,8) right off the bed, you can see, it is common practice not to use some kind of function to create a (10,8) matrix. Say: rand,ones, zeros, or some other tricks say reshape((1:1:80), 10, 8).
This is an old question but I'm posting my answer in case anyone stumbled across the same problem. Assuming that you're trying to get 32 digits precision, use
M=vpa(zeros(10,8)).