2

I have a dataframe called barometre2013 with a column called q0qc that contain this numbers:

[1] 15  1  9 15 9  3  6  3  3  6  6 10 15  6 15 10

I want to add +1 to the numbers that are >= 10, so the result should be this:

[1] 16  1  9 16 9  3  6  3  3  6  6 11 16  6 16 11  

I have tried this code:

if (barometre2013$q0qc > 9) {
  barometre2013$q0qc <- barometre2013$q0qc + 1
}

But this add +1 to all the numbers without respecting the condition:

[1] 16  2  10 16 10  4  7  4  4  7  7 11 16  7 16 11

How can I do what I want ?

Thank a lot.

Marine Leroi
  • 23
  • 1
  • 6
  • 7
    `barometre2013$q0qc <- barometre2013$q0qc + (barometre2013$q0qc >= 10)` – IceCreamToucan May 02 '18 at 21:05
  • alternative: `barometre2013$q0qc[barometre2013$q0qc>=10] <- barometre2013$q0qc+1` – Jilber Urbina May 02 '18 at 21:05
  • `ifelse` is the vectorized version of `if`. The other comments are efficient and fancy, but the basic way would be `barometre2013$q0qc <- barometre2013$q0qc + ifelse(barometre2013$q0qc >= 10, 1, 0)` – Gregor Thomas May 02 '18 at 21:13
  • 1
    @Jilber, that code won't work. You mean `b2$q[b2$q >= 10] <- b2$q[b2$q >= 10] + 1` (variable names abbreviated) –  May 02 '18 at 21:35
  • 1
    @Gregor, I don't think @Jilber's code is fancy. It's the simplest basic way of conditionally altering a vector. New R users should grok this before using `ifelse`. –  May 02 '18 at 21:37
  • @dash2 you're right! I forgot index rhs – Jilber Urbina May 02 '18 at 21:39

2 Answers2

2

When you executed:

if (barometre2013$q0qc > 9) {
  barometre2013$q0qc <- barometre2013$q0qc + 1
}

... you should have seen a warning about "only the first value being evaluated". That first value in barometre2013$q0qc was 15 and since it was TRUE, then that assignment was done on the entire vector. ifelse or Boolean logic are approaches suggested in the comments for conditional evaluation and/or assignment. The first:

barometre2013$q0qc <- barometre2013$q0qc + (barometre2013$q0qc >= 10) 

... added a vector of 1 and 0's to the starting vector; 1 if the logical expression is satisfied and 0 if not. If you wanted to add something other than one (which is the numeric value of TRUE) you could have multiplied that second term by the desired increment or decrement.

Another approach was to use ifelse which does do a conditional test of its first argument on returns either the second or third argument on an item-by-item basis:

barometre2013$q0qc <- barometre2013$q0qc + ifelse(barometre2013$q0qc >= 10, 1, 0)

The third approach suggested by dash2 would be to only modify those values that meet the condition. Note that this method requires having the "test vector on both sides of the assignment (which is why dash2 was correcting the earlier comment:

barometre2013$q0qc[barometre2013$q0qc>=10] <- 
                      barometre2013$q0qc[barometre2013$q0qc>=10]+ 1
IRTFM
  • 258,963
  • 21
  • 364
  • 487
  • Thanks a lot for the explanation ! – Marine Leroi May 03 '18 at 15:12
  • Sometimes it's useful to know what went wrong so you can better remember what _not_ to do in the future. Remember to pay attention to the text of warning messages. – IRTFM May 03 '18 at 17:06
  • Btw I choose to do the third approach ;) – Marine Leroi May 04 '18 at 13:21
  • I'm sorry to do that, but I am really desperate. Do you think you can answer my other question? I really need help. Please!! https://stackoverflow.com/questions/50178993/tolower-function-and-merging-two-dataframes – Marine Leroi May 04 '18 at 16:51
-6
    data <- c(15,1,9,15,9,3,6,3,3,6,6,10,15,6,15,10)

    data2 <- 

    as.numeric( 
      for(i in data){
      if(i >= 10){ i = i +1 }
      print(i)
      }
    )

class(data)
class(data2)
Ray Kodiak
  • 69
  • 1
  • 13
  • 1
    it is really not what you should do, I am sorry to say. Your object `data2` will be empty because you are not assigning anything, and you should really consider vectorised operation in R. So it is wrong and doesnt' answer the question – denis May 02 '18 at 21:47
  • I can consider whatever I want :- ) in this free world! haha maybe it will teach him loops at the same time :- ) – Ray Kodiak May 02 '18 at 21:51
  • object is not empty, same class as started with, gives correct answer, I realize that Vector is the right way to go, but that wasn't specified in the question, maybe it will teach him other things too and get the right answers, so there... – Ray Kodiak May 02 '18 at 22:01