Having syntax errors with if statements - r

I have the following question:
In the imported data frame, I need to create a new column named “profit_margin_flag” whose value is computed as follows [profit margin = Profit / Sales].
a.If the profit margin is negative, the new column should have the value “negative”.
b.If the profit margin is positive and less than 10%, the new column should have the value “low margin”.
c.If the profit margin is 10% or more, but less than 25%, the new column should have the value “standard margin”.
d.If the profit margin is 50% or more, the new column should have the value “high margin”.
I coded this:
orders$profit_margin_flag <- orders$Profit/orders$Sales
n <- nrow(orders)
`for (i in (1:n))`
{
if(orders$profit_margin_flag[i] < 0)
{orders$profit_margin_flag[i] <- "negative"}
else if(orders$profit_margin_flag[i] >0 && <.10)
{orders$profit_margin_flag[i]<- "low margin"}
else if(orders$profit_margin_flag[i] >= .10 && < .25)
{orders$profit_margin_flag[i]<- "standard margin"}
else if(orders$profit_margin_flag[i] >= .50)
{orders$profit_margin_flag[i]<- "high margin"}
}
I receive this error:
else if(orders$profit_margin_flag[i] >0 && <.10)
#Error: unexpected 'else' in " else"
# {
+ orders$profit_margin_flag[i]<- "low margin"
+ }
else if(orders$profit_margin_flag[i] >= .10 && < .25)
Error: unexpected 'else' in "else"
{orders$profit_margin_flag[i]<- "standard margin"}
else if(orders$profit_margin_flag[i] >= .50)
Error: unexpected 'else' in " else"
{orders$profit_margin_flag[i]<- "high margin"}
}
Error: unexpected '}' in "}"

As #mickey pointed out, && < .10 isn't valid syntax.
That being said, do you want to replace profit_margin_flag's value with "negative" etc. (as you specific in the OP) or do you want it assigned to a new variable?
I cleaned up your code a little bit (with the flag being assigned to a new variable profit_margin_flag and the margin values originally being stored in profit_margin) and this should work.
orders <- data.frame(profit_margin = c(-2, 0.07, 0.14, 11), profit_margin_flag = rep_len(NA, 4))
for(i in 1:nrow(orders)){
+ if(orders$profit_margin[i] < 0){
+ orders$profit_margin_flag[i] <- "negative"
+ }
+ else if(orders$profit_margin[i] > 0 && orders$profit_margin[i] < 0.10){
+ orders$profit_margin_flag[i]<- "low margin"
+ }
+ else if(orders$profit_margin[i] >= 0.10 && orders$profit_margin[i] < 0.25)
+ {
+ orders$profit_margin_flag[i]<- "standard margin"
+ }
+ else if(orders$profit_margin[i] >= 0.50)
+ {
+ orders$profit_margin_flag[i]<- "high margin"
+ }
+ }
orders
# profit_margin profit_margin_flag
# 1 -2.00 negative
# 2 0.07 low margin
# 3 0.14 standard margin
# 4 11.00 high margin

Related

Function for confidence intervals error code {

together with you, I have recently made the following function (the content is not important right now). It seems to be correct but when I try to process it, the following error turns up: Error: unexpected '}' in " }". Do you know what I´ve made wrong?
Here´s the function, thank you in advance (btw I have checked every bracket):
Edit: Now it works:
CI <- function(x, s, z, Fall) {
if (Fall == "Fall1") {
result <- mean(x) + c(-1,1)* qnorm(1-z/2)*(s/sqrt(length(x)))
} else if (Fall == "Fall2") {
result <- mean(x) + c(-1,1)* qt(p=1-a/2, df=length(x)- 1)*(sd(x)/sqrt(length(x)))
} else if (Fall == "Fall3") {
result <-mean(x)+c(-1,1)qnorm(1-z/2(s/sqrt(length(x))))
} else if (Fall == "Fall4"){
result <- mean(x)+c(-1,1)qt(p=1-a/2, df=length(x)-1)(sd(x)/sqrt(length(x)))
} else {result<-NA}
return(result)
}
CI(x=x, s=15, z=0.05, Fall="Fall1")
There are couple of errors - 1) else would not have a condition check, instead use else if, 2), the values to compare should be quoted "Fall1"
CI <- function(x, mean, sd, z, Fall)
{
if (Fall == "Fall1") {
result <- mean(x) + c(-1, 1) * qnorm(1 - z / 2) * (sd / sqrt(length(x)))
} else if (Fall == "Fall2") {
result <-
mean(x) + c(-1, 1) * qt(p = 1 - a / 2, df = length(x) - 1) * (sd(x) / sqrt(length(x)))
} else if (Fall == "Fall3") {
result <- mean(x) + c(-1, 1) * qnorm(1 - z / 2 *
(sd / sqrt(length(x))))
} else if (Fall == "Fall4") {
result <-
mean(x) + c(-1, 1) * qt(p = 1 - a / 2, df = length(x) - 1) * (sd(x) / sqrt(length(x)))
}
else {
result <- NA_real_
}
return(result)
}

If & ifelse statement in R

As the new user in R, I met few problems when I tried to evaluate a.
Code:
// time2 are numbers //
a = d3$Time2
b = c(...)
for (i in 1:65){
for (j in 1:1762){
if( (a[j]>=1474161415+900*(i-1))&(a[j]<1474161415+900*i) ){ a[j] = b[j] }
}
}
Results:
Error in if ((a[j] >= 1474161415 + 900 * (i - 1)) & (a[j] < 1474161415 + :
missing value where TRUE/FALSE needed
Also I have tried:
ifelse( ((a[j]>=1474161415+900*(i-1)) & (a[j]<1474161415+900*i)) , a[j]=b[j])
Results:
-unexpected '=' in -ifelse( ((a[j]-=1474161415+900-(i-1)) &
(a[j]-1474161415+900-i)) , a[j]=--

KnapSack dynamic programming in R with recursive function

I created this simple code in R to solve the Knapsack program with a recursive funtion
n <- c(0,1,2,3,4)
v <- c(10,40,30,50)
w <- c(5,4,6,3)
k <- 10
myfunction <- function(n,k){
if (n==0 | k==0){
output <- 0
} else if (w[i] > k) {
output <- myfunction[i-1,w]
} else {
output <- max(v[i]+ myfunction(i-1, k-w[i]),myfunction(i-1,k))
}
return(myfunction)
}
However, I don't get a value as an output, but the whole function. For example if I put in:
myfunction(4,10)
I don't get an value of 90, but the whole funtion typed out.
these are the values
There were several errors beyond the ones pointed out by #etienne. Here's an annotated debugging session. First we fix the returned object:
> myfunction <- function(n,k){
+ if (n==0 | k==0){
+ output <- 0
+ } else if (w[i] > k) {
+ output <- myfunction[i-1,w]
+ } else {
+ output <- max(v[i]+ myfunction(i-1, k-w[i]),myfunction(i-1,k))
+ }
+ return(output)
+ }
> myfunction(4,10)
Error in if (w[i] > k) { : argument is of length zero
Obviously neither w nor k are of length zero which suggests it must be i. (As also pointed out by etienne). Looking at your code it appears you actually intended i to be the index that decreased until the terminating condition was met. So replace n by i in the few instances where it appeared:
> myfunction <- function(i,k){
+ if (i==0 | k==0){
+ output <- 0
+ } else if (w[i] > k) {
+ output <- myfunction[i-1,w]
+ } else {
+ output <- max(v[i]+ myfunction(i-1, k-w[i]),myfunction(i-1,k))
+ }
+ return(output)
+ }
> myfunction(4,10)
Error in myfunction[i - 1, w] :
object of type 'closure' is not subsettable
So you also made the mistake of using square-brackets where parentheses (aka bracket in the non-US sections of the world) were needed:
> myfunction <- function(i,k){
+ if (i==0 | k==0){
+ output <- 0
+ } else if (w[i] > k) {
+ output <- myfunction(i-1,w)
+ } else {
+ output <- max(v[i]+ myfunction(i-1, k-w[i]),myfunction(i-1,k))
+ }
+ return(output)
+ }
> myfunction(4,10)
[1] 90
Success, well, almost. Most of the warnings are because you used | instead of || in one of the conditionals:
Warning messages:
1: In if (i == 0 | k == 0) { :
the condition has length > 1 and only the first element will be used
2: In if (w[i] > k) { :
the condition has length > 1 and only the first element will be used
3: In if (i == 0 | k == 0) { :
the condition has length > 1 and only the first element will be used
4: In if (i == 0 | k == 0) { :
the condition has length > 1 and only the first element will be used
5: In if (i == 0 | k == 0) { :
the condition has length > 1 and only the first element will be used
6: In if (i == 0 | k == 0) { :
the condition has length > 1 and only the first element will be used
So replace that instance with a logical ||. To deal with the other warning that didn't seem to sabotage your logic, realize that w[i] is length-0 when i == 0, so add a logical clause in the conditional that first tests for that possibility and use the correct "double-AND-sign" ( && ):
myfunction <- function(i,k){
if (i==0 || k==0){
output <- 0
} else if (length( w[i]) && w[i] > k) {
output <- myfunction(i-1,w)
} else {
output <- max(v[i]+ myfunction(i-1, k-w[i]), myfunction(i-1,k))
}
return(output)
}
Now you get:
> myfunction(4,10)
[1] 90

Nested "for" loops in R

I'm an R novice with what I hope is a simple question. I've got a couple of nested loops I'm running and can't seem to get the output that I'm expecting.
I want to keep track of the balance in the internal loop. Each iteration represents 1 year. At the end of 15 years, I want to write the final balance to InvTotal for each of 4 simulations.
My final output should be 3 vectors (1 for each investment) of length 4, showing the final cumulative value for each investment at the end of 4 simulations.
My code is below. Any assistance you could provide would be a huge help.
Thank you!
Investment1_Balance <- 10000
Investment2_Balance <- 10000
Investment3_Balance <- 10000
Inv1Returns <- c(0, 1000, -500, 500)
Inv2Returns <- c(0, -9000, 30000, 10000)
Inv3Returns <- c(0, 4000, -1000, -2000)
Inv1Outcome = NULL
Inv2Outcome = NULL
Inv3Outcome = NULL
Inv1Total = NULL
Inv2Total = NULL
Inv3Total = NULL
random = NULL
for (j in 1:4)
{
for (i in 1:15 )
{
random[i] = runif(1, 0, 1)
Inv1Outcome[i] = if (random[i] <= .25){Investment1_Balance + Inv1Returns[1]}
else if (random[i] > .25 & random[i] <= .50){Investment1_Balance + Inv1Returns[2]}
else if (random[i] > .50 & random[i] <= .75){Investment1_Balance + Inv1Returns[3]}
else {Investment1_Balance + Inv1Returns[4]}
Inv2Outcome[i] = if (random[i] <= .20){Investment2_Balance + Inv2Returns[1]}
else if (random[i] > .20 & random[i] <= .30){Investment2_Balance + Inv2Returns[2]}
else if (random[i] > .30 & random[i] <= .70){Investment2_Balance + Inv2Returns[3]}
else ({Investment2_Balance + Inv2Returns[4]})
Inv3Outcome[i] = if (random[i] <= .50){Investment3_Balance + Inv3Returns[1]}
else if (random[i] > .50 & random[i] <= .70){Investment3_Balance + Inv3Returns[2]}
else if (random[i] > .70 & random[i] <= .90){Investment3_Balance + Inv3Returns[3]}
else ({Investment3_Balance + Inv3Returns[4]})
Investment1_Balance[i] =+ Inv1Outcome[i]
Investment2_Balance[i] =+ Inv2Outcome[i]
Investment3_Balance[i] =+ Inv3Outcome[i]
}
Inv1Total[j] = Investment1_Balance[15]
Inv2Total[j] = Investment2_Balance[15]
Inv3Total[j] = Investment3_Balance[15]
}
Inv1Total
Inv2Total
Inv3Total
Welcome to stackoverflow! There are a couple of points that you should consider while trying to figure out why your code isn't working as expected:
"Start small" : In your case here, I would start with one investment, maybe even with one simulation. This would verify if the logic of the calculation is fine, without distracting myself with other numbers.
"Seeing is believing" : Try to print intermediate results, so you can trace the calculation bugs.
Applying the previous, a first debugging would would look something like:
Investment1_Balance <- 10000
Inv1Returns <- c(0, 1000, -500, 500)
Inv1Outcome = NULL
Inv1Total = NULL
random = NULL
for (j in 1:4) { # Loop over simulations
cat("\n\n\nSimulation ", j, ": Investment balance:" , Investment1_Balance)
for (i in 1:15) { # Loop over years
random[i] = runif(1, 0, 1)
Inv1Outcome[i] = if (random[i] <= .25){Investment1_Balance + Inv1Returns[1]}
else if (random[i] > .25 & random[i] <= .50){Investment1_Balance + Inv1Returns[2]}
else if (random[i] > .50 & random[i] <= .75){Investment1_Balance + Inv1Returns[3]}
else {Investment1_Balance + Inv1Returns[4]}
Investment1_Balance[i] =+ Inv1Outcome[i]
cat("\n Year: ", i, "- Outcome:", Inv1Outcome[i], "- Final balance: " , Investment1_Balance[i])
}
Inv1Total[j] = Investment1_Balance[15]
}
Inv1Total
.
You can see a couple of problems with the numbers printed :
The outcome is always the same as the balance. This suggests that there might be a problem with the addition.
Let's try to debug that:
> x = 10
> x =+ 2
> x
[1] 2
Apparently, the =+ isn't working as expected. So we have to correct that : Investment1_Balance[i+1] = Investment1_Balance[i] + Inv1Outcome[i]
.
When printing the initial investment balance for each simulation, we can see that the first simulation is fine (Simulation 1 : Investment balance: 10000). But for the other simulations we get (Simulation 2 : Investment balance: 10000 9500 10000 10000 10500 11000 9500 11000 10000 10500 10500 10000 10000 11000 11000).
This suggests a problem with the initialization. Each simulation takes the output of the previous and starts with it. The logic of that is not quite correct. The simple solution would be resetting Investment1_Balance <- 10000 at the beginning of each simulation. It would even make sense in this case to reset all the Balance and Outcome variables.
.
Here is the new code after debugging :
Inv1Returns <- c(0, 1000, -500, 500)
random = NULL
Inv1Total = NULL
for (j in 1:4) { # Loop over simulations
Investment1_Balance <- 10000
Inv1Outcome = NULL
cat("\n\n\nSimulation ", j, ": Investment balance:" , Investment1_Balance)
for (i in 1:15) { # Loop over years
random[i] = runif(1, 0, 1)
Inv1Outcome[i] = if (random[i] <= .25){Investment1_Balance + Inv1Returns[1]}
else if (random[i] > .25 & random[i] <= .50){Investment1_Balance + Inv1Returns[2]}
else if (random[i] > .50 & random[i] <= .75){Investment1_Balance + Inv1Returns[3]}
else {Investment1_Balance + Inv1Returns[4]}
Investment1_Balance[i+1] = Investment1_Balance[i] + Inv1Outcome[i]
cat("\n Year: ", i, "- Outcome:", Inv1Outcome[i], "- Final balance: " , Investment1_Balance[i])
}
Inv1Total[j] = Investment1_Balance[15]
}
Inv1Total
Check if the output is now correct. If so, you can go ahead and add Inv2 and Inv3 as well.

Error .. missing value where TRUE/FALSE needed

I have been trying to run this code (below here) and I have gotten that message "Error in if (temp[ii] == 0) { : missing value where TRUE/FALSE needed"...
temp = c(2.15, 3.5, 0, 0, 0, 1.24, 5.42, 6.87)
tm = length(temp)
for (i in 1:tm){
if (temp[i] == 0) {
counter3 = 1
last = temp[i - 1]
for (ii in i + 1:tm){
if (temp[ii] == 0) {
counter3 = counter3 + 1
}
if (temp[ii] != 0) {
nxt = temp[i + counter3]
}
}
}
}
Your problem is that temp[ii] is returning NA because ii goes out of bounds:
ii = i + 1:tm #Your declaration for ii
ii = 1:tm + 1:tm #Evaluates to
So ii will definitely be larger than tm (and therefore length(temp) at some point.
In order to better understand/debug for loops, consider printing just the indices:
for(i in 1:tm)
{
print(i)
for(ii in i + 1:tm)
print(ii)
}
At a guess I'm going to say that this is in R - if so I'm guessing that this line:
if (temp[i] == 0) (or temp[ii] == 0)
is resulting in an NA, and if conditions must have a TRUE or FALSE value.
Using a debugger if you can, I'd interrogate the value of temp[i] before the if block.
Difficult without knowing the language, but i think the issue is that the value in ii can be greater than the length of temp when i is at its upper bound. I'd have expected an index out of range or something similar but, without knowing the language, who knows! Hope you get your problem fixed.

Resources