This question already has answers here:
R: Break for loop
(2 answers)
Closed 8 years ago.
How can I end a for loop if a condition is met inside it?
I want to break a for loop once t = 1 for example, but as of now I am only breaking out of an if statement inside the for loop.
t = 0
x = matrix()
for (i in 1:10){
if (t == 1){
break }
t = t + 0.01
x[i] = t
}
Assuming that you mean, for (i in 1:101), you won't get a value equal to 1 in the loop because .01 cannot be exactly represented in binary.
With the modified for statement, the 100'th value is not exactly equal to 1:
x[100] - 1
## [1] 6.661338e-16
To break when something "exceeds or equals" another value, you would use >=. That is, modify the test to read if (t >= 1) { break }. In general, you should not use == to compare floating-point numbers.
Related
This question already has an answer here:
if {...} else {...} : Does the line break between "}" and "else" really matters?
(1 answer)
Closed 1 year ago.
It works, but I wonder why tis is correct
if (one_time_cost_year_zero != 0) { EIW_TPI_flag = 1
} else {EIW_TPI_flag = 0}
while this results in an error
if (one_time_cost_year_zero != 0) { EIW_TPI_flag = 1 }
else {EIW_TPI_flag = 0}
What's the logic behind that?
Because R would not know that your if -else statement is not finished yet (since only the if () line is also valid R...) compare
1 + 2
+ 3
vs
1 + 2 +
3
In R if we want to split a command over multiple lines we need to either leave a bracket open (as in the if -else example) or have a "hanging" operator at the end of the line (there are also "multiline" strings, but they are not really commands per se)....
Then, the error you are seeing results from the fact that we can't beginn a command with else (like we can't start a command with in, | etc.)
Accordingly, we could also write:
if (one_time_cost_year_zero != 0) { EIW_TPI_flag = 1 } else
{EIW_TPI_flag = 0}
x <- 1:19
count <- 0
for (i in x) {
if atranspose * T5_5_FBEETLES[i, 3:6]>cutoff
count=count+1
}
print(count)
Hello, I am trying to do a for loop in R. In this for loop, I am multiplying a 1x4 matrix (atranspose in this case) and the third through sixth columns of a table (the table is T5_5_FBEETLES in this case) row by row (hence the i in x, so going through the first 19 rows) and I'm comparing it to a number with the variable name of cutoff. If the multiplication ends up with something greater than the cutoff number, I want count to increase by 1. I know from doing this by hand that by the end count should be 19, but for whatever reason my for loop returns 1 for my count variable and I keep getting these two errors:
unexpected symbol in:
"for (i in x) {
if atranspose"
unexpected '}' in "}"
Can anyone explain to me why these two errors are occurring, and how I can fix up my for loop so that it can return the correct count?
You are getting an error because your if statement crosses a line and thus needs some curly braces:
x <- 1:19
count <- 0
for (i in x) {
if (atranspose * T5_5_FBEETLES[i, 3:6]>cutoff) {
count=count+1
}
}
print(count)
This will then give you another error because the logical check of the if statement will return a vector, so it needs to be wrapped in an any:
x <- 1:19
count <- 0
for (i in x) {
if (any(atranspose * T5_5_FBEETLES[i, 3:6]>cutoff)) {
count=count+1
}
}
print(count)
I want to calculate the difference of two columns of a dataframe containing times. Since not always a value from the same column ist bigger/later, I have to do a workaround with an if-clause:
counter = 1
while(counter <= nrow(data)){
if(data$time_end[counter] - data$time_begin[counter] < 0){
data$chargingDuration[counter] = 1-abs(data$time_end[counter]-data$time_begin[counter])
}
if(data$time_end[counter] - data$time_begin[counter] > 0){
data$chargingDuration[counter] = data$time_end[counter]-data$time_begin[counter]
}
counter = counter + 1
}
The output I get is a decimalvalue smaller than 1 (i.e.: 0,53322 meaning half a day)... However, if I use my console and calculate the timedifference manually for a single line, I get my desired result looking like 02:12:03...
Thanks for the help guys :)
I made a function to to compute the sum of I(Xi
my.ecdf<- function(x,y) {
if(!is.null(dim(y)))
stop("y has more than one dimension")
n<-length(x)
i<-1:n
p<-if(x[i]<y) 1 else {
0
}
(sum(p))/n
}
But when I run it with input (rnorm(11),6), I get this error:
Warning message:
In if (x[i] < y) 1 else { :
the condition has length > 1 and only the first element will be used
Any ideas? I'm new to r so sorry if it's something obvious. (Also I don't want to use the for loop)
There are a number of issues in your code:
1) Whats the point of x[1:length(x)] in the if statement? Right now these are meaningless and can be dropped:
n<-length(x)
i<-1:n
x[i]
2) If statement accepts a logical argument not a vector of logical, you can consider adding all() any() etc like
if(all(x < y)) 1 else {0}
or use ifelse() statement for the assignment
3) Finally from what I can understand you overcomplicate things and the whole thing can be written as one-liner:
sum(x < y)/length(x)
This is a logical vector of the same length as y
is.null(dim(y))
You're using it as a logical test. An object with a length greater than 1 can't be unambiguously interpreted by the if statement. Consider if (TRUE FALSE FALSE TRUE) <do something>. When should you do that thing?
If you want to make sure y doesn't have more than one dimension, do
if(length(dim(y)) > 1){
stop("message")
}
I have a loop I want to execute that depends on the output of the previous loop in the code. This is the code;
holder <- list()
if (i < historyLength) movement <- movementType(relAngle, angleThreshold)
else if (i > historyLength-1) {
# Array to store speeds
speedHistory <- array(historyLength)
n = historyLength-1
# get the speeds from the previous n (hisoryLength) "Movements"
for (j in seq(1, length(historyLength))){
speedHistory [n] = R[i-j, 6]
n-1
}
if (!bayesFilter(speedHistory, minSpeed, GPS_accy)) movement <- "non-moving"
else if(bayesFilter(speedHistory, minSpeed, GPS_accy)) movement <- movementType(relAngle, angleThreshold)
}
holder [[i]] <- (movement)
for (t in seq(1, length(holder))){
if (t == t-1)
changes <- 0
else if (t != t-1)
changes <- 1
}
You cannot see the beginning of loop but it results in a column of data called 'movements.'
I have attempted to temporarily store the 'movements' in the object 'holder.' What i want then is for the bottom for loop to go through 'holder' and label changes as either 0 or 1 in another column. Basically if the next 'movement' is not equal to the previous record the change as 0 and so forth. I think the problem is with the object 'holder' perhaps?
Currently I'm getting it to loop but it's only printing out a column of '1's.'
Any help much appreciated! Thanks.
Currently get the following output:
Movement Changes
left 1
right 1
forward 1
non-moving 1
non-moving 1
Think the problem lies in the list where movements are stored? Sorry, if I knew where the problem was I'd be more specific. Really new to this!
I end up with a data frame with column headers "Distance" "Speed" "Heading" "Movement" and "Changes." It's looping fine but for some reason Changes reults in a column of 1's as above. Is there an obvious mistake below?:
holder[[i]] <- (movement)
for (t in seq(1, length(holder))){
if (t == t-1)
changes <- 0
else if (t != t-1)
changes <- 1
I have also tried this, but then it doesn't loop at all.
holder[[i]] <- (movement)
for (t in seq(1, length(holder))){
if (holder[t] == holder[t-1])
changes <- 0
else if (holder[t] != holder[t-1])
changes <- 1
I'm currently getting this error: Error in holder[[t - 1]] : attempt to select less than one element
for the following code:
holder <- list(movement)
for (t in length(holder)){
if (holder[[t]] == holder[[t-1]])
changes <- 0
else changes <- 1
This is too long for a comment so I'm putting this as answer (actually it might answer your problem):
As I already mentioned in a comment to your previous question, you should have a look at what is seq(1, length(holder)) and so what you are doing when you put if (t == t-1) : you are doing something like "if 1==0" which cannot be TRUE.
You need to go with "the second version" of your loop (or, actually, without a loop...), which compares the right things, except that holder is a list so you need to either define it as a vector or use double brackets (holder[[t]]).
You don't need another if after else (what you are actually "saying" to R is "if A is true then do something, else, if 'opposite A' is true then do something else" but, necessarily, if A is not TRUE, then 'opposite A' is...
So something like:
for (t in seq(length(holder))){
if (holder[[t]] == holder[[t-1]]) changes <- 0 else changes <- 1
}
Please consider spending some time on the answer from your previous question to understand why your solution didn't work and why the answer provided did. (This includes reading documentations for the different functions and also take a look at the values your variable can take, e.g. running the loop, one "turn" at a time).