0

I'm new to and I have a question about if() statements.

My data looks like:

Var1  Var2
4     2
6     2
5     1
3     3
2     1

I want to create a new variable called Var3. Something like

if Var2 = 1 then do; Var3 = Var1*30; end; else;
if Var2 = 2 then do; Var3 = Var1*4; end; else;
if Var2 = 3 then do; Var3 = Var1*1; end; else;

Any help to create the code will be appreciated.

M--
  • 25,431
  • 8
  • 61
  • 93
Mr.M
  • 111
  • 1
  • 9
  • 2
    `dplyr::case_when` is great for this. – Jon Spring May 21 '19 at 22:07
  • https://stackoverflow.com/questions/38649533/case-when-in-mutate-pipe – M-- May 21 '19 at 22:09
  • 2
    Case-when logic is good if you have complicated expressions, but R also allows you to avoid step-by-painstaking-step expressions. For instance, this is essentially a look-up table in this example - e.g. `dat$Var1 * c(30, 4, 1)[dat$Var2]` – thelatemail May 21 '19 at 22:18

2 Answers2

2

1) switch Using DF shown reproducibly in the Note at the end try using switch as shown here. No packages are used.

transform(DF, Var3 = Var1 * sapply(Var2, switch, 30, 4, 1))

giving:

  Var1 Var2 Var3
1    4    2   16
2    6    2   24
3    5    1  150
4    3    3    3
5    2    1   60

See ?switch for more information.

2) arithmetic Another approach is to use an arithmetic statement that evaluates to the desired value. This also uses no packages.

transform(DF, Var3 = Var1 * ((Var2 == 1) * 30 + (Var2 == 2) * 4 + (Var2 == 3) * 1))

2a) A variation of this is:

transform(DF, Var3 = Var1 * outer(Var2, 1:3, "==") %*% c(30, 4, 1))

3) subscripting This also works:

transform(DF, Var3 = Var1 * c(30, 4, 1)[Var2])

4) factor Another approach is to create a factor and then convert that back to numeric:

transform(DF, Var3 = Var1 * as.numeric(as.character(factor(Var2, labels = c(30, 4, 1)))))

Note

Lines <- "Var1  Var2
4     2
6     2
5     1
3     3
2     1"
DF <- read.table(text = Lines, header = TRUE)
G. Grothendieck
  • 254,981
  • 17
  • 203
  • 341
  • Thank you for your answer. The method you used on 2) arithmetic worked very well. I just faced one issue which is I couldn't find Var3 on the dataset. I tried to use the following ```DF$SKM <- transform(DF, Var3 = Var1 * ((Var2 == 1) * 30 + (Var2 == 2) * 4 + (Var2 == 3) * 1))``` I couldn't find Var3. Is there a way to make the new variable part of the dataset – Mr.M May 22 '19 at 21:18
  • You need `DF <- transform(...` or you can give it another name so that you don't overwrite the original. – G. Grothendieck May 22 '19 at 23:10
0

In syntax similar to what you listed:

DF$Var3 = with(DF,
  ifelse(Var2 == 1, Var1 * 30,
    ifelse(Var2 == 2, Var1 * 4, 
      ifelse(Var2 == 3, Var1, NA))))

But other methods will be faster to write and faster to run, once you get the hang of them.

Gregor Thomas
  • 136,190
  • 20
  • 167
  • 294