0

I am trying to learn how to use function and apply. So first I wanted to understand how both works.

Here is a basic example. I am creating a function that, depending in the value of a column, use one algorith or another:

datos = data.frame(replicate(5,sample(0:10,10,rep=TRUE)))

calculo <- function(variable) {
  
  aa = variable * 2
  
  if (variable < 5) {
    aa = 0
  }
  
  return(aa)
}

datos$Y1 = apply(datos, 1, FUN=function(x) calculo(datos$X1))

My simple idea in this example is that:

  • If the value of X1 is < 5, then value is 0.
  • If >= 5, then multiply by 2.

When I apply it, I think that the condition is applied to all the values in datos$X1 at the same time, instead of going row by row. So it isn´t working in the way I thought.

Is there a way to apply the condition row by row?

Thanks

GonzaloReig
  • 77
  • 1
  • 6
  • Hi :) just to avoid repeating things you might already know, what information have you already checked? (ex: `?apply`, [SO post](https://stackoverflow.com/questions/3505701/grouping-functions-tapply-by-aggregate-and-the-apply-family), etc.) – Paul Dec 11 '20 at 08:12
  • I would also generally recommend to use the arrow operator for assigning objects instead of the = sign, e.g. `aa <- ...` or `datos <- ...` – deschen Dec 11 '20 at 08:17

1 Answers1

1

Just use

datos$Y1 <- calculo(datos$X1)

You could also streamline your function a bit (not sure which version is faster):

calculo <- function(variable) {
  
  aa <- ifelse(variable < 5, 0, variable * 2)
  return(aa)
}

which gives (might look different for you due to the randomness of the generation of datos:

   X1 X2 X3 X4 X5 Y1
1   5  0  3  8  9 10
2   3  6  1  3  3  0
3   6  2  5  2  5 12
4   8  0  9  8  2 16
5   1  6 10  5  0  0
6   6  1  7  9 10 12
7   0  0 10  1 10  0
8  10  8  8  1  4 20
9   9  0  6  5  3 18
10  0  9  0  5  4  0

UPDATE: my preferred way in the tidyverse.

library(tidyverse)
datos <- datos %>%
  mutate(Y1 = if_else(X1 < 5, 0, X1 * 2))
deschen
  • 10,012
  • 3
  • 27
  • 50
  • Nice use of `ifelse()`, I came up with something very similar using `if{}else{}` structure (witch is not vectorized) but it shows a warning. Thus @GonzaloReig, you might consider using this new `calculo()` function from deschen. – Paul Dec 11 '20 at 08:29
  • I wouldn't necessarily call the "ifelse" function "new". ;-) – deschen Dec 11 '20 at 08:30
  • Yes ^^ I mean the `calculo()` one, I edited the comment. – Paul Dec 11 '20 at 08:33
  • @GonzaloReig: also see my updated post in case you prefer a tidyverse solution. – deschen Dec 11 '20 at 08:51