1

I am having trouble putting some code into functions/ running a loop in R

I am wanting to replace variables (var1,2,3,4) in a dataframe based on the value in the 'var99' column.

I am able to do this the following way:

var1 =  c(1, 2, 1, 2)
var2 = c(3, 2, 1, 2)
var3 = c(0.4, 2, 1, 2)
var4 = c(1, 2, 1, 2)
n1 = c(10, 14, 12, 10)
n2 = c(5, 3, 12, 10)
var99 = c('se', 'se', 'sd', 'sd')
mydata=data.frame(var1, var2, var3, var4, n1, n2, var99)    
mydata<- mutate(mydata, var1 = ifelse(var99=="se",(var1*n1^0.5), var1))

mydata<- mutate(mydata, var2 = ifelse(var99=="se",(var2*n2^0.5), var2))

mydata<- mutate(mydata, var3 = ifelse(var99=="se", (var3*n2^0.5), var3))

mydata<- mutate(mydata, var4 = ifelse(var99=="se", (var4*n2^0.5), var4))

But this will get unwieldy with more variables and I would prefer to have e.g.

varnames = c(var1, var2, var3, var4)

That I would then loop through. Would anybody be able to advise how to construct a function/use lapply as I have been unsuccessful in my attempts

RobMcC
  • 392
  • 2
  • 7
  • 20
  • Please share a reproducible example – Sotos Jul 06 '18 at 13:31
  • Maybe check `mutate_at` to apply your function on multiple columns. Not very easy to help more without any data. – AntoniosK Jul 06 '18 at 13:31
  • I have added a reproducible example above – RobMcC Jul 06 '18 at 13:38
  • You don't need to loop through the variables, but also you have to check for which variable you need to use `n1` or `n2`, right? Just making sure this is not a typing mistake. – AntoniosK Jul 06 '18 at 13:44
  • Yes sorry, this was not clear; it will sometimes be n1 and other times n2. But I imagine if I had a working solution I would be happy to run it twice once with n1 and the other time with n2 . – RobMcC Jul 06 '18 at 13:47

1 Answers1

1

I hope the following examples help you to pick the best approach for your objective

var1 =  c(1, 2, 1, 2)
var2 = c(3, 2, 1, 2)
var3 = c(0.4, 2, 1, 2)
var4 = c(1, 2, 1, 2)
n1 = c(10, 14, 12, 10)
n2 = c(5, 3, 12, 10)
var99 = c('se', 'se', 'sd', 'sd')
mydata=data.frame(var1, var2, var3, var4, n1, n2, var99)

library(dplyr)

# applying one function to those specific 4 columns
mydata %>% mutate_at(vars(var1:var4), funs(ifelse(var99=="se",(.*n2^0.5), .)))

#       var1     var2      var3     var4 n1 n2 var99
# 1 2.236068 6.708204 0.8944272 2.236068 10  5    se
# 2 3.464102 3.464102 3.4641016 3.464102 14  3    se
# 3 1.000000 1.000000 1.0000000 1.000000 12 12    sd
# 4 2.000000 2.000000 2.0000000 2.000000 10 10    sd


# applying different functions to different columns
mydata %>% 
  mutate_at(vars(var1), funs(ifelse(var99=="se",(.*n1^0.5), .))) %>%
  mutate_at(vars(var2:var4), funs(ifelse(var99=="se",(.*n2^0.5), .)))

#       var1     var2      var3     var4 n1 n2 var99
# 1 3.162278 6.708204 0.8944272 2.236068 10  5    se
# 2 7.483315 3.464102 3.4641016 3.464102 14  3    se
# 3 1.000000 1.000000 1.0000000 1.000000 12 12    sd
# 4 2.000000 2.000000 2.0000000 2.000000 10 10    sd


# applying different functions to those specific 4 columns

mydata %>% 
   mutate_at(vars(var1:var4), funs(n1 = ifelse(var99=="se",(.*n1^0.5), .), 
                                   n2 = ifelse(var99=="se",(.*n2^0.5), .)))

#   var1 var2 var3 var4 n1 n2 var99  var1_n1  var2_n1  var3_n1  var4_n1  var1_n2  var2_n2   var3_n2  var4_n2
# 1    1    3  0.4    1 10  5    se 3.162278 9.486833 1.264911 3.162278 2.236068 6.708204 0.8944272 2.236068
# 2    2    2  2.0    2 14  3    se 7.483315 7.483315 7.483315 7.483315 3.464102 3.464102 3.4641016 3.464102
# 3    1    1  1.0    1 12 12    sd 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 1.0000000 1.000000
# 4    2    2  2.0    2 10 10    sd 2.000000 2.000000 2.000000 2.000000 2.000000 2.000000 2.0000000 2.000000
AntoniosK
  • 15,991
  • 2
  • 19
  • 32
  • 1
    For the last example, you can do it with one call to `mutate_at` like the following: `mydata %>% mutate_at(vars(var1:var4), funs(n1 = ifelse(var99=="se",(.*n1^0.5), .), n2 = ifelse(var99=="se",(.*n2^0.5), .)))` – acylam Jul 06 '18 at 13:59
  • Good point! I'll update my answer. – AntoniosK Jul 06 '18 at 14:27