Luis
Luis

Reputation: 1584

Mutate data frame via function in R

Sorry for the basic question, but I could not find an example in this forum to solve this question. I've tried this one and this one.

I want to change / create a new variable in my data.frame via function in R and tidyverse:

Example:

crivo <- function(x) {
  x <<- x %>% 
    mutate(resp_1 = if_else(MEMO_RE01 == 0,"VN","FP")) %>% 
    mutate(resp_2 = if_else(MEMO_RE02 == 1,"VP","FN"))
  }
crivo(memo_re)

My data.frame name is "memo_re", but I'll use this function to other datasets as well, just by changing the x argument. R is creating a new data.frame named x instead of creating a new variable in "memor_re" (original dataset). In other words, I want to assign a function to do that:

memo_re <- memo_re %>% mutate(resp_1 = if_else(MEMO_RE01 == 0,"VN","FP"))

But I need to change many datasets and because of that, I want to be able to specify which dataset I'll change.

reproducible code

library(tidyverse)
memo_re <- data.frame(MEMO_RE01=rep(c(0,1),100), MEMO_RE02=c(0,1))

crivo <- function(x) {
  x <<- x %>% 
    mutate(resp_1 = if_else(MEMO_RE01 == 0,"VN","FP")) %>% 
    mutate(resp_2 = if_else(MEMO_RE02 == 1,"VP","FN"))
}
crivo(memo_re)

Upvotes: 0

Views: 350

Answers (1)

Steven
Steven

Reputation: 3294

R is doing exactly what you've asked it to do. In your crivo function definition, you've written your function to assign the new data frame you've created called x to the R environment. That's what the <<- operator does. After running your code, use ls() to see what's in your environment, then look at x. You'll see everything is there, just as you've asked it to be, including the correctly mutate x dataframe.

> memo_re <- data.frame(MEMO_RE01=rep(c(0,1),100), MEMO_RE02=c(0,1))
> 
> crivo <- function(x) {
+   x <<- x %>% 
+     mutate(resp_1 = if_else(MEMO_RE01 == 0,"VN","FP")) %>% 
+     mutate(resp_2 = if_else(MEMO_RE02 == 1,"VP","FN"))
+ }
> crivo(memo_re)
> ls()
[1] "crivo"   "memo_re" "x"      
> head(x)
  MEMO_RE01 MEMO_RE02 resp_1 resp_2
1         0         0     VN     FN
2         1         1     FP     VP
3         0         0     VN     FN
4         1         1     FP     VP
5         0         0     VN     FN
6         1         1     FP     VP

Now, if you wanted to have crivo() return something that you could then assign any name you wanted, you should use

crivo <- function(x) {
  x %>% 
    mutate(resp_1 = if_else(MEMO_RE01 == 0,"VN","FP"), 
           resp_2 = if_else(MEMO_RE02 == 1,"VP","FN"))
}

Note that I haven't used the <<- operator anywhere. As a result, the crivo fx will be returning the mutated x dataframe so that you could do

new <- memo_re %>% crivo()

This way, you can pipe anything you want to crivo and assign it to any new variable. Alternatively, if you just wanted to call the function on memo_re, you can do that too:

memo_re <- memo_re %>% crivo()

Note that the "classic" way to write a function is to use return() to specify what you want a fx to return. If you don't use return() (as I haven't above), R will return whatever is in the last line. Here, it's just the mutate dataframe.

Upvotes: 2

Related Questions