amisos55
amisos55

Reputation: 1979

Skipping a line of code when a condition is met in R

I am trying to skip a line of code based on a condition. Here my sample dataset looks like.

df <- data.frame(
  id = c(12,25,31,47),
  b = c("cat.1","cat.2","cat.3","cat.2"),
  drop = c(FALSE,TRUE,TRUE,TRUE))

> df
  id     b  drop
1 12 cat.1 FALSE
2 25 cat.2  TRUE
3 31 cat.3  TRUE
4 47 cat.2  TRUE

Based on the b and drop variables, I print different out and combine them in the output. I would like to skip a line code when drop = FALSE.

output <- c()
for(i in 1:nrow(df)) {
  if (df$b[i] == "cat.1") {
    out <- paste0("Item_first_",df$id[i],"_",df$drop[i])
    
  } else if(df$b[i] == "cat.2") { 
    out <- paste0("Item_second_",df$id[i],"_",df$drop[i])
    
  } else {
    out <- paste0("Item_others_",df$id[i],"_",df$drop[i])
  }
  output <- c(output, out) 
}

print(output)
[1] "Item_first_12_FALSE" "Item_second_25_TRUE" "Item_others_31_TRUE" "Item_second_47_TRUE"

In this case, "Item_first_12_FALSE" needs to be dropped from the output because this row in the dataset has the drop=FALSE.

I know there is next function in for() loops but it avoids the whole iteration. And also, it looks easy to fix by just removing the FALSE from the dataset but I specifically want to omit it inside of the ifelse because of the other condition combinations. IN this case, I need only skip this part meeting the drop=`FALSE' condition.

 if (df$b[i] == "cat.1") {
    out <- paste0("Item_first_",df$id[i],"_",df$drop[i])
    
  }

The desired output would be:

"Item_second_25_TRUE" "Item_others_31_TRUE" "Item_second_47_TRUE"

Upvotes: 1

Views: 1426

Answers (3)

Liman
Liman

Reputation: 1300

Unless you have to have the for loop

output <- unlist(ifelse((df$b == "cat.1"),list(NULL),paste("Item_second_",df$id,df$drop, sep="_")))

print (output)
#  "Item_second__25_TRUE" "Item_second__31_TRUE" "Item_second__47_TRUE"

Upvotes: 1

ekoam
ekoam

Reputation: 8844

Maybe just do something like this

with(df, sprintf("Item_%s_%d_%s", dplyr::case_when(b == "cat.1" ~ "first", b == "cat.2" ~ "second", TRUE ~ "others"), id, drop)[drop])

Upvotes: 1

stlba
stlba

Reputation: 767

Try wrapping your if-else within another if statement:

output <- c()
for(i in 1:nrow(df)) {
  if (df$drop[i] == T) {
    if (df$b[i] == "cat.1") {
      out <- paste0("Item_first_",df$id[i],"_",df$drop[i])
      
    } else if(df$b[i] == "cat.2") { 
      out <- paste0("Item_second_",df$id[i],"_",df$drop[i])
      
    } else {
      out <- paste0("Item_others_",df$id[i],"_",df$drop[i])
    }
    output <- c(output, out)
  }  
}
> print(output)
[1] "Item_second_25_TRUE" "Item_others_31_TRUE" "Item_second_47_TRUE"

Upvotes: 1

Related Questions