If lattice in function - r

I am trying to create a function that returns different values when the variable is in different ranges.
nhpp_lambda <- function(t) {
for (t in 1:365) {
if (t >= "1" && t <= "59")
lambda = 20.83
else if (t >= "60" && t <= "151")
lambda = 11.02
else if (t >= "152" && t <= "243")
lambda = 11.68
else if (t >= "244" && t <= "334")
lambda = 26.41
else if (t >= "335" && t <= "365")
lambda = 20.83
}
return(lambda)
}
how come this doesn't work? it still just always returns 20.83??

In the function you have defined you return the value of lambda after the loop has finished, and in the last iteration of the loop, the value is always 20.83. If you remove the loop, it will work, e.g.,
nhpp_lambda <- function (t) {
if (t >= 1 && t <= 59)
lambda = 20.83
else if (t >= 60 && t <= 151)
lambda = 11.02
else if (t >= 152 && t <= 243)
lambda = 11.68
else if (t >= 244 && t <= 334)
lambda = 26.41
else if (t >= 335 && t <= 365)
lambda = 20.83
return(lambda)
}
nhpp_lambda(5)
nhpp_lambda(55)
nhpp_lambda(120)
nhpp_lambda(285)
nhpp_lambda(340)

Firstly, you're taking $t$ as a function argument, but then defining $t$ through the loop $1:365$, so that $t$ cycles in values from $1,2,\dots,365$. Remove the for() loop, it serves no purpose.
Secondly, you're comparing a number $t$ to strings "1","59",etc. Remove the quoations, you should be comparing $t$ to integers not characters/strings. Here is the correct code
nhpp_lambda <- function(t) {
if (t >= 1 && t <= 59)
lambda = 20.83
else if (t >= 60 && t <= 151)
lambda = 11.02
else if (t >= 152 && t <= 243)
lambda = 11.68
else if (t >= 244 && t <= 334)
lambda = 26.41
else if (t >= 335 && t <= 365)
lambda = 20.83
return(lambda)
}

Related

Combining of logical conditions in IF statement

I just notice the if condition below:
//1
if ((i >= 0) != (j >= 0))
return false;
is just a short way for:
//2
if((i>=0 && j < 0) || (i < 0 && j >=0))
return false;
Going from 1. to 2. takes some time to figure out, but how do we deduce the logic to go from 2. to 1.?
If you have any two boolean statements A and B then A != B means that they are different. I.e. either A is true and B is false, or A is false and B is true. This goes also the other way if A is true and B is false, or A is false and B is true, then A does not equal B.
In other words (A != B) = ((A && !B) || (!A && B)). Therefore, statement 1 and 2 are the same
If you feel my argumentation is imprecise, you can use truth tables to proof it rigorous mathematically:
A
B
A!=B
(A && !B)
(!A && B)
(A && !B) || (!A && B))
true
true
false
false
false
false
true
false
true
true
false
true
false
true
true
false
true
true
false
false
false
false
false
false
If we call (i >= 0) something arbitrary like A and (j >= 0) something else like B then it stands to reason that (i < 0) is just Not A (often shown as !A) and (j < 0) would be Not B or !B
Meaning this block:
if((i>=0 && j < 0) || (i < 0 && j >=0))
return false;
Can be represented as:
if ((A && !B) || (!A && B))
return false;
else // you haven't specified this part but it's implied
return true;
Now, if we approach this as:
How do we get to the true value?
Then you realise it's the same as:
if ((A && B) || (!A && !B))
return true;
else
return false;
Then we can call (A && B) something else like C; so it becomes:
if (C || !C)
return true;
else
return false;
So, expanding out again, we can get:
if (A && B)
return true;
else if (!(A && B))
return true;
else
return false;
So, that's:
if ((i >= 0) && (j >= 0))
return true;
else if (!( (i >= 0) && (j >= 0) ) )
return true;
else
return false;
Which can evaluate to:
if (True && True)
return true;
else if (False && False)
return true;
else
return false;
Showing that it's as simple as:
if ( (i >= 0) == (j >= 0) )
return true;
else // if ( (i >= 0) != (j >= 0) )
return false;
So, we've gone around the houses but we've worked our way down from statement 2 to statement 1.
NOTE: Adam's answer is more concise and is accurate from a pure logic perspective; this is more to provide a broader overview as I know that some people learn better when they can see the process.

If loop - Argument is of length zero - error

I do have the following code for a loop, which basically only updates the column "decay rate" based on whether or not the column "RPK_cap" is higher than a certain threshold which is exogenously given(in scenario 1 it is 1200, in Scenario 2 it is 1300 etc). If that is the case than I want to decrease the decay rate by multiplying it my 0.9. This is done for all countries (column: iso) and years(column: year) which are in the data.table. When I am using scenario 1 data the column "RPK_cap" will be filled with scenario 1 data and if I choose scenario 2 the column "RPK_cap" will be filled with scenario 2 data respectively.
And my problem is the following:
This loop works ONLY for scenario 1.
If I am using scenario 2 I get the error message:
"Error in if (price_el_int_aviation_RPK$RPK_Cap[price_el_int_aviation_RPK$iso == :
argument is of length zero"
I really tried a lot and I just donĀ“t know what the problem is here. Does anyone know what the problem is?
This is the data.table
data.table_example
if (scenario == "1") {
for (j in unique(price_el_int_aviation_RPK$iso)) {
for (i in unique(price_el_int_aviation_RPK$year[price_el_int_aviation_RPK$iso == j])) {
if (price_el_int_aviation_RPK$RPK_cap[price_el_int_aviation_RPK$iso == j & price_el_int_aviation_RPK$year == i] > 1200) {
price_el_int_aviation_RPK$decay_rate[price_el_int_aviation_RPK$iso == j & price_el_int_aviation_RPK$year >= i] <- price_el_int_aviation_RPK$decay_rate[price_el_int_aviation_RPK$iso == j & price_el_int_aviation_RPK$year >= i] * 0.90
}
}
}
} else if (scenario == "2"){
for (j in unique(price_el_int_aviation_RPK$iso)) {
for (i in unique(price_el_int_aviation_RPK$year[price_el_int_aviation_RPK$iso == j])) {
if (price_el_int_aviation_RPK$RPK_Cap[price_el_int_aviation_RPK$iso == j & price_el_int_aviation_RPK$year == i] > 1300) {
price_el_int_aviation_RPK$decay_rate[price_el_int_aviation_RPK$iso == j & price_el_int_aviation_RPK$year >= i] <- price_el_int_aviation_RPK$decay_rate[price_el_int_aviation_RPK$iso == j & price_el_int_aviation_RPK$year >= i] * 0.95
}
}
}
} else if (scenario == "3"){
for (j in unique(price_el_int_aviation_RPK$iso)) {
for (i in unique(price_el_int_aviation_RPK$year[price_el_int_aviation_RPK$iso == j])) {
if (price_el_int_aviation_RPK$RPK_Cap[price_el_int_aviation_RPK$iso == j & price_el_int_aviation_RPK$year == i] > 1400) {
price_el_int_aviation_RPK$decay_rate[price_el_int_aviation_RPK$iso == j & price_el_int_aviation_RPK$year >= i] <- price_el_int_aviation_RPK$decay_rate[price_el_int_aviation_RPK$iso == j & price_el_int_aviation_RPK$year >= i] * 0.95
}
}
}
} else if (scenario == "4"){
for (j in unique(price_el_int_aviation_RPK$iso)) {
for (i in unique(price_el_int_aviation_RPK$year[price_el_int_aviation_RPK$iso == j])) {
if (price_el_int_aviation_RPK$RPK_Cap[price_el_int_aviation_RPK$iso == j & price_el_int_aviation_RPK$year == i] > 1500) {
price_el_int_aviation_RPK$decay_rate[price_el_int_aviation_RPK$iso == j & price_el_int_aviation_RPK$year >= i] <- price_el_int_aviation_RPK$decay_rate[price_el_int_aviation_RPK$iso == j & price_el_int_aviation_RPK$year >= i] * 0.95
}
}
}
} else if (scenario == "5"){
for (j in unique(price_el_int_aviation_RPK$iso)) {
for (i in unique(price_el_int_aviation_RPK$year[price_el_int_aviation_RPK$iso == j])) {
if (price_el_int_aviation_RPK$RPK_Cap[price_el_int_aviation_RPK$iso == j & price_el_int_aviation_RPK$year == i] > 1600) {
price_el_int_aviation_RPK$decay_rate[price_el_int_aviation_RPK$iso == j & price_el_int_aviation_RPK$year >= i] <- price_el_int_aviation_RPK$decay_rate[price_el_int_aviation_RPK$iso == j & price_el_int_aviation_RPK$year >= i] * 0.99
}
}
}
}else{}
It's hard to answer in specifics because we cannot see your data.
But the error you see
"Error in if (price_el_int_aviation_RPK$RPK_Cap[price_el_int_aviation_RPK$iso == : argument is of length zero"
is because price_el_int_aviation_RPK$iso is of length zero - it's a vector without anything in it!
Here's a minimal example of the problem
# Create a vector of length zero
a <- c()
# Prove it's length is zero
length(a)
# [1] 0
# This is a minimal example of what's going wrong with scenario 2 in your script
if(a == 2) { print("it works") }
Error in if (a == 2) if (a == 2) { : argument is of length zero

Loop returns error: 'argument is of length zero'

i <- 2
j <- 0
for (i in 2:1000) {
if(return.prime(i)){j = j + 1}
i = i + 1
}
I want to check how many prime numbers there are in 1 to 1000 using my own function return.prime which returns TRUE when the number input is a prime and FALSE when the number input is not prime. The return.prime function is the function below and it is correct.
return.prime <- function(d){
if(d ==1 ){print(FALSE)}
if (d == 2){
print(TRUE)
}
if(d !=2 && d!=1){
if(any(d %% (2:(d-1)) == rep(0,d-2))==TRUE){
print(FALSE)}
else
print(TRUE)
}
}
The problem is when I run my program it says:
[1] TRUE
Error in if (return.prime(i)) { : argument is of length zero
I do not know what causes the length zero.
R doesn't work that way. You're just having the function print the word "TRUE" or "FALSE". Instead, you need to ?return TRUE or FALSE. Consider:
return.prime <- function(d){
if(d==1){ return(FALSE) }
if(d==2){ return(TRUE) }
if(d !=2 && d!=1){
if(any(d %% (2:(d-1)) == rep(0,d-2))==TRUE){
return(FALSE)
} else{
return(TRUE)
}
}
}
i <- 2
j <- 0
for (i in 2:1000) {
if(return.prime(i)){j = j + 1}
i = i + 1
}
j # [1] 168

Why does this Fibonnacci recursion fails to return an answer for n > 2?

This recursion code doesn't give an output for n > 2. It works if I include the last if condition as else. Why does this happen?
fib <- function(n){
if(n == 0){
0
}
if(n ==1 ){
1
}
if(n == 2){
1
}
if (n > 2) {
print(n)
fib(n-1) + fib(n-2)
}
}
A function by default returns the result of the last value evaluated inside the function. Here you have a bunch of separate if statements that will all be evaluated (your function doesn't return early at any point. Observe
f <- function(a) {
-99
if (a==1) {111}
if (a==2) {22}
}
f(1)
# -- doesn't return anything --
f(2)
# [1] 22
f(3)
# -- doesn't return anything --
When 'a==1', That middle if statement would evaluate to 111 but that value is then discarded when you run the next if statement just like the -99 value was before it. The last expression that was evaluated in this function is the if (a==2) {22} and that will either return 22 or it will return NULL. It won't return the previous values because it has no idea how those would be related without the else statement.
fib <- function(n){
if(n == 0){
return(0)
}
if(n ==1 ){
return(1)
}
if(n == 2){
return(1)
}
if (n > 2) {
print(n)
return(fib(n-1) + fib(n-2))
}
}
Or you could turn those into if/else staments so only one "thing" will be returned
fib <- function(n){
if(n == 0){
0
} else if(n ==1 ){
1
} else if(n == 2){
1
} else if (n > 2) {
print(n)
fib(n-1) + fib(n-2)
}
}

Wrong result in a PARI-implementation

I tried to implement an algorithm to calculate power towers
modulo m. Below the procedure tower should calculate
2^3^...^14^15 (mod m) and tower2 should calculate
15^14^...^3^2 (mod m). But for m = 163 , tower2
produces a wrong answer. I found out that a immediate
result is 0 and the procedure does not get this.
Can anyone fix the error ?
The procedure powmod is implemented and works perfectly :
powmod(basis,exponent,modul)={if(exponent==0,hilf=1);if(exponent>0,bin=binary(exponent);hilf=basis;hilf=hilf-truncate(hilf/modul)*modul;for(stelle=2,length(bin),hilf=hilf^2;if(bin[stelle]==1,hilf=hilf*basis);hilf=hilf-truncate(hilf/modul)*modul));hilf}
? tower
%19 = (p,q,r)->if(q==0,hilf=1);if(q==1,hilf=p);if(q==2,hilf=powmod(p,p,r));if(q>
2,x=[];for(j=1,q,x=concat(x,r);r=eulerphi(r));hilf=14^15;forstep(j=13,2,-1,r=x[j
-1];if(r>=2,hilf=powmod(j,hilf,r);w=factorint(r);w=component(w,2);while(hilf<vec
max(w),hilf=hilf+r))));component(Mod(hilf,r),2)
? tower2
%20 = (p,q,r)->if(q==0,hilf=1);if(q==1,hilf=p);if(q==2,hilf=powmod(p,p,r));if(q>
2,x=[];for(j=1,q,x=concat(x,r);r=eulerphi(r));hilf=3^2;forstep(j=13,2,-1,r=x[j-1
];if(r>=2,hilf=powmod(17-j,hilf,r);w=factorint(r);w=component(w,2);while(hilf<ve
cmax(w),hilf=hilf+r))));component(Mod(hilf,r),2)
?
The reason your code doesn't work is that you (recursively) compute x^n (mod r) as x^(n mod phi(r)) and this isn't true unless gcd(x,r) = 1.
Also, you don't need powmod since Mod(basis,modul)^expo is built-in.
Here's a general possibility :
\\ x[1]^(x[2]^( ...^ x[#x])) mod m, assuming x[i] > 1 for all i
tower(x, m) =
{ my(f = factor(m), P = f[,1], E = f[,2]);
chinese(vector(#P, i, towerp(x, P[i], E[i])));
}
towerp(x, p, e) =
{ my(q = p^e, i, t, v);
if (#x == 0, return (Mod(1, q)));
if (#x == 1, return (Mod(x[1], q)));
if (v = valuation(x[1], p),
t = x[#x]; i = #x;
while (i > 1,
if (t >= e, return (Mod(0, q)));
t = x[i]^t; i--);
if (t * v >= e, return (Mod(0, q)));
return (Mod(x[1], q)^t);
);
Mod(x[1], q)^lift(tower(x[2..#x], (p-1)*p^e));
}
? tower([2..15], 163)
%1 = Mod(162, 163)
? tower(Vecrev([2..15]), 163)
%2 = Mod(16, 163)

Resources