If else statement doesnt work and cant figure out why - r

Can someone explain why my else part of my function doesnt work?
finaltable;
Duplicate Digit6 Digit7 Digit7a Digit7b Digit7c Digit7d Dead carried
137401 137401 2017681 2017681 2018047 2018047 2018219 1 0
137402 137402 2017731 2017731 2017856 2017856 2018279 0 0
w <- function(finaltable){
if (nchar(tail(names(finaltable),1) >= nchar(c("carried")))) {(ncol(finaltable)-2)
} else (ncol(finaltable)-1)
}
I have colnames (Duplicate, digit, dead, carried). I want the last digit column. Depending on the day I will have tail(names(finaltable),1 = carried or dead. If carried, I need to subtract two columns, if dead then one column. However, I have several columns named dead or carried that are associated with number. However, the max dead will be is dead99. Thus I have a max of 6 characters.
I then want to dump my function into below.
SubtractROW<-finaltable[paste(ROWS), w(finaltable)];
BarCODEtable<-cbind(ILS,ROWS,SubtractROW);
BarCODEtable;

Here's your function, corrected so that it returns the right values:
w <- function(finaltable){
if (nchar(tail(names(finaltable),1)) >= nchar("carried")) {
(ncol(finaltable)-2)
} else {
ncol(finaltable)-1
}
}
w(finaltable) # if last column is dropped
#[1] 7
The problem was in your if statement, where a ) was at the wrong place. Running your original if statement results in:
nchar(tail(names(finaltable),1) >= nchar(c("carried")))
#[1] 4
where it should be
nchar(tail(names(finaltable),1)) >= nchar("carried")
#[1] FALSE
But as commented above, you could more easily use
max(which(grepl("^Digit", names(finaltable))))
instead.

Related

How to fix errors in this function

Write a function named countConsecutivePairs that accepts a numeric vector as an argument and counts the pairs of consecutive elements whose difference is less than 2.
You should stop the execution and print an appropriate error message if the argument is not numeric.
Here is my code
countConsecutivepairs=function(z){
if(!(is.vector(z)))
stop("Error"
if(class(z)!="numeric")
stop("Error")
for(i in z) {
if(abs(z[i]-z[i+1])!=2){
next
}
print(c(z[i],z[i+1])
}
}
I get a bunch of errors when I do this. And Im not sure how to fix it.
You miss several ) in your code.
And thanks to #Jan, as #Ace123 use z[i]'s in code and also want to check consecutive elements, we should call those elements by i against length of z.
countConsecutivepairs<- function(z){
if(!(is.vector(z))){
stop("Error")
}
if(class(z)!="numeric"){
stop("Error")
}
for(i in 1:(length(z)-1)) {
if(abs(z[i]-z[i+1])!=2){
next
}
print(c(z[i],z[i+1]))
}
}
countConsecutivepairs(c(1,2,3,5,7))
[1] 3 5
[1] 5 7

Attempting a for loop in R

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)

After checking condition need to add a column and assign a value

I have a data frame(final1) with few columns
for(i in final1$Total.Tyres)
{
if(final1$Total.Tyres[i] >= 500){
final1$flag_tyres[i]<-1
} else {
final1$flag_tyres[i]<-0
}
}
I need to check if tires are greater than 500 if so need to assign 1 adding a new column flag_tyres
when tried the above code give me below error
Error in if (final1$Total.Tyres[i] >= 500) { :
missing value where TRUE/FALSE needed
You may want to consider vectorizing your code instead of using for to loop over the rows, saves you typing, hassle and is faster:
final1$flag_tyres <- ifelse(final1$Total.Tyres >= 500, 1, 0)
Simple mistake, should be 1:length(final1$Total.Tyres) in the outer loop. Alternatively, you could vectorize the result, as already answered.

Loop will not execute in R

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).

nested if statment in R

I'm trying to implement following thing in R, but I'm new in R and my code doesn't work.
I have matrix A, I did coordinates changes .
I want to write two function:
1) give the element of matrix, given coordinates
2) give the coordinates given number.
the pseudo code is right, the only problem is my syntax. can somebody correct it ?
f<- as.numeric(readline(prompt="Please enter 10 to get coordinate of number,and 20 to get the number > "));
if(p==10){
# give the number, given coordinates
i<- as.numeric(readline(prompt="Pleae enter i cordinate > "));
j<- as.numeric(readline(prompt="Pleae enter j cordinate > "));
if (i>0&j<0) return A[5+i,5+j]
if (i>0&j>0) return A[5+i,5+j]
if (i<0&j>0) return A[5+i,5-j]
if (i<0&j<0) return A[5+i,5-j]
}else if (p==20){
#give the cordinate, given number
coordinate <- which(A==number)
[i,j]<-A[2-coordinate[0],coordinate[1]-2]
}
}
Warning: what if i or j is equal to zero? Next, make a single variable which is the decimal representation of binary i,j, That is,
if(p==10){
x <- (i>0) + 2*(j>0) +1
# x takes on values 1 thru 5. This is because switch requires nonnegative integer
switch(x,
return A[5+i,5+j],
return A[5+i,5+j],
return A[5+i,5+j],
return A[5+i,5+j]) # change the +/- indices as desired
}else{
#etc.
And, finally, you should make this a function, not a collection of commands.
Edit - I skipped this before, but: you cannot call an index of 0 so you need to fix a number of things in the line [i,j]<-A[2-coordinate[0],coordinate[1]-2]
The syntax is as follows:
x <- 4
if (x == 1 | x == 2) print("YES")

Resources