2

Firstly I aplogise because this question has no doubt been answered in another page eg How do I use a macro variable in R? (Similar to %LET in SAS) and Pass string as name of attached data column name but I’ve read them, watched Youtube tutorials, thought that the function command was what I wanted and I just can’t get it to work. I’m very new to programming as a whole, and only few days in for R, and I’m sure I’m missing something due to my lack of experience or understanding of even where to start.

In SAS I would do it like this

%Macro DV (var1, var2);
Proc mixed …
Model &var1 = &var2 …
Data &var1_&var2…
%mend DV;
%DV (VAS, Hyd)
%DV (SOM, Hyd)
%DV (GAS, Hyd)

The variables (eg. VAS, Hyd) that I’m calling in are column labels, they get called in, the column analysed in a mixed model and, with a bit more code, the dataset gets exported with a filename according to the variables analysed. I’m not trying to do a lmer in R I’m using the rmcorr package and want to change the columns that get analysed. The original expression, that works, looks like

VASCor.rmc <- rmcorr(participant = Subject, measure1 = Hyd, measure2 = VAS, dataset = mydata)
plot(VASCor.rmc,mydata, overall = T, lty=1, xlab = "Hyd", ylab = "VAS")

A working dataset can be found below. So just working on the first expression I tried the following, thinking that the var1 and var2 would get inserted in the correct places but I just end up with an error "object 'var2' not found".

Allrmcorr <- function(var1, var2){
var1.var2.rmc <- rmcorr(participant = Subject, measure1 = var2, measure2 = var1 , dataset = Results2)
}
Allrmcorr("VAS","Hyd")
Allrmcorr("VAS","Hyd")

I've attempted a number of expressions and probably spent long enough trying to figure it out to have just rewritten the expression time, I'm not closer but being stubborn I want to know the better way for next time. Any help would be greatly appreciated.

mydata <- data.frame(
Subject = c(1,1,1,1,1,2,2,2,2,2,3,3,3,3,3),
Time = c(1:5,1:5,1:5),
VAS= runif(15),
Hyd =runif(15),
GAS= runif(15)
)
Joe
  • 62,789
  • 6
  • 49
  • 67
Robells
  • 23
  • 4
  • 1
    Without knowing anything about the `rmcorr` function, it looks like you just need to `return` your variable that you create. Add `return(var1.var2.rmc)` to the end of your function and you should see the value. You'd then create your new variables like `vas.hyd.rmc <- Allrmcorr("VAS", "Hyd")` – tblznbits Aug 27 '17 at 14:58
  • There is no need for a return statement in this case. R always returns the last value in a function. – Stefan F Aug 27 '17 at 16:30

1 Answers1

1

I am not familiar with rmcorr but your problem stems from how your function takes input paramets. Look carefully at your code:

rmcorr(participant = Subject, measure1 = var2, measure2 = var1 , dataset = Results2)

takes measure1 and measure as bare names input (so, a language element, not a string literal like "var1" (in quotes).

While you pass string literals to the function with Allrmcorr("VAS","Hyd"), rmcorr wants bare names that it evaluets in them frame of dataset. All this is probably a bit complicated an off-putting if you are new to R. I recommend reading "Advanced R" by Hadley Wickham if you want to dive deeper into the topic (especially the chapters on functions and lazy evaluation).

A simple solution to your problem - which is similar to how macro variables work - is constructing your expression as a string and then evaluating it:

Allrmcorr <- function(var1, var2, dat){
  ds <- dat
  eval(parse(text = (sprintf(
    "rmcorr(participant = Subject, measure1 = %s, measure2 = %s, dataset = ds)", var1, var2
  ))))
}

Allrmcorr("VAS", "Hyd", mydata)

This has severe disadvantages when it comes to performance and debuggability of your code; however, I was not able to find a better solution to your problem since the internal implementation of rcmorr is somewhat weird.

Stefan F
  • 2,573
  • 1
  • 17
  • 19
  • `get()` may not work since variable by itself does not exist in global environ. The `rmcorr` method references the column from *dataset* arg. – Parfait Aug 27 '17 at 17:48
  • Hmm it doesn't have to be in the _global_ environment for get to work, but I am also not 100% sure get will work here. Maybe of op produces a reproducible example we can play around a bit. `get(var2, Results2)` or simpler `Result2[[var2]]` should work in any case, but this is a bit cumbersome. – Stefan F Aug 27 '17 at 18:49
  • 1
    It may not be OP's fault but authors of package. Seeing their [source code](https://github.com/cran/rmcorr/blob/master/R/rmcorr.R), params are expected as *symbol* types and then `eval()` returns the value. Most functions usually receive string params to allow the dynamic nature OP requires. I may raise an issue on their repo. – Parfait Aug 27 '17 at 21:09
  • @StefanF I've added a reproducible example now, my apologies for not doing that earlier. Thank you, I've had a go at your suggestions get(var1) get(var2, Results2) and Results2[[var2]] but they don't seem to work. – Robells Aug 28 '17 at 02:41
  • @Parfait By that does it mean that it's not possible? I'm happy to raise it with the authors since I have been in contact with them previously, though you obviously have a much better understanding of what's going on than I do. – Robells Aug 28 '17 at 02:46
  • Okay I have a solution. Im between doors and I will try to add some explanation to the answer later. It is very ugly by R standards, I hope someone else comes up with something better. – Stefan F Aug 28 '17 at 05:21
  • I raised an [issue](https://github.com/cran/rmcorr/blob/master/R/rmcorr.R) on their Git repo referencing this question. I even played around as @StefanF does with `eval(parse(...))` which became messy and not recommended. Use this solution in the meanwhile until their response or package update. Authors seem active as repo shows some update 5 days ago. – Parfait Aug 28 '17 at 11:47
  • 1
    @Parfait I think you might want to contact the author directly. You posted your issue to a cran-mirror repository, that is not connected to the author at all – Stefan F Aug 29 '17 at 15:06