1

I'm sorry if this has been asked before. I have checked numerous questions about using if-else inside for loops to no avail. I must be misinterpreting the answers. I've edited my code multiple times to avoid different fatal errors and/or unanticipated outputs (incl. no change and/or only the else statement being evaluated).

What I want the loop to do: Check if Column A has a negative value and Column B is equal to 2. If both conditions are true, put a 0 in Column C; otherwise, copy the value from Column B as is to Column C. Ultimately, I also want to do the reverse - swap 0s for 2s when Column A is negative.

Thanks!

condition = c(0,1,2)
ppt1 = sample(condition, 124, replace = T) 
ES = rnorm(n = 124)
key = as.data.frame(cbind(ES,ppt1))
key$recoded = rep(NA, 124)

This creates a desired input like this:

key[1:6,]
          ES ppt1 recoded
1 -0.1893987    0      NA
2 -0.3840249    2      NA
3  0.7405880    2      NA
4 -1.1683384    0      NA
5  0.6675387    0      NA
6  0.3662369    2      NA

Here are my two ifelse attempts:

for(i in nrow(key)){ 
  ifelse((key$ES[i] < 0) && (key$ppt1[i] == 2),key$recoded[i] == 0,key$recoded[i] == key$ppt1[i]) 
}

for (i in 1:nrow(key)) {
  if(key$ES[i] < 0 && key$ppt1 == 2) {
    key$recoded[i] == 0
  } else {
    key$recoded[i] == "key"
  }
}

The desired outcome would be like this:

key[1:6,]
          ES ppt1 recoded
1 -0.9729880    0       2
2  0.5695559    1       1
3  1.1376975    2       2
4  0.8132510    2       2
5  0.8482997    1       1
6 -0.9434207    2       0

See how in rows 1 & 6, the $recoded column has swapped 0 and 2.

SKOR2
  • 39
  • 7
  • 2
    It's easier to help if you provide a [reproducible example](https://stackoverflow.com/questions/5963269/how-to-make-a-great-r-reproducible-example) with sample input and desired output that can be used to test and verify possible solutions. Use `set.seed()` when using random functions so we can get the same values as you. – MrFlick Jan 29 '18 at 16:50
  • @MrFlick I added an example of a desired outcome. I couldn't get set.seed to work though. I tried set.seed(5) before running ppt1 = sample(condition, 124, replace = T) and kept getting different numbers. – SKOR2 Jan 29 '18 at 17:02

2 Answers2

1

You use == to assign instead of = or <-

and you forget to put [i] in variable key$ppt1

Use this

for (i in 1:nrow(key)) {
   if(key$ES[i] < 0 && key$ppt1[i] == 2) {
      key$recoded[i] = "0"
   } else {
      key$recoded[i] = key$ppt1[i]
   }
}
Winicius Sabino
  • 1,486
  • 8
  • 17
1

ifelse is vectorized, so you don't need a for loop to use it. & is the vectorized version of &&. This should do what you want, and be quite a bit faster than the for loop:

key$recoded = ifelse((key$ES < 0) & (key$ppt1 == 2), 0, key$ppt1) 

You might also like the with function to not type your data name so much. Inside with() you can use column names without the dataframe$ beforehand.

key$recoded = with(key, ifelse(ES < 0 & ppt1 == 2, 0, ppt1))
Gregor Thomas
  • 136,190
  • 20
  • 167
  • 294
  • Ugh. I thought I saw ifelse written this way and wondered if I could have used it. Thanks. I'll switch to this. I actually have a large dataframe to work with, so this might be helpful. – SKOR2 Jan 29 '18 at 20:18