-3

I am trying automate a simple task in R using a function. C is list of character variables. mydata- is the dataset.

Basically, I need to give each of the strings in vector C as an input to the function.

dataset:

mydata <- structure(list(a = c(1L, 1L, 1L, 1L, 0L, 0L, 1L, 0L), b = c(4L,3L, 1L, 2L, 1L, 5L, 2L, 2L), c = c(1L, 1L, 1L, 1L, 1L, 1L, 1L,1L), d = c(0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L), t = c(42L, 34L, 74L,39L, 47L, 8L, 36L, 39L), s = c(0L, 0L, 0L, 0L, 0L, 1L, 0L, 0L)), .Names = c("a", "b", "c", "d", "t", "s"), row.names = c(NA,8L), class = "data.frame") 

code:

c<-c("a","b","c","d")

plot<-function()
 for (i in c) 
{
  fit<-survfit(Surv(s,t)~paste(i), dat=mydata)
  ggsurvplot(fit, pval = TRUE)  
}
plot()

I m facing the following error:

Error in model.frame.default(formula = Surv(mydata$s, mydata$t) ~ paste(i), : variable lengths differ (found for 'paste(i)')

I have tried the reformulate as well:

plot<-function() for (i in c) { survfit(update(Surv(s,t)~., reformulate(i)), data=mydata) ggsurvplot(fit, pval = TRUE)
} plot()

but this code also gives this error:

Error in reformulate(i) : object 'i' not found 

Any help to make this code work?

Thanks

riz
  • 15
  • 5
  • 1
    It's easier to help when you provide some sort of [reproducible example](http://stackoverflow.com/questions/5963269/how-to-make-a-great-r-reproducible-example) with sample input data so we can actually run and test code. – MrFlick Sep 10 '16 at 04:12
  • thanks for the comment. sample input data is provided – riz Sep 10 '16 at 06:45

1 Answers1

1

Building formulas dynamically can be tricky. Rather than

fit(Surv(mydata$s,mydata$t)~paste(i), dat=mydata)

use

fit(update(Surv(s,t)~., reformulate(i)), data=mydata)

You should avoid using $ with formulas. Here reformualte() helps to build a formula from a string and update combines parts of formulas. See the help pages for these functions if you would like more details.

Here's the full working version with the sample inout

#sample input
mydata <- structure(list(a = c(1L, 1L, 1L, 1L, 0L, 0L, 1L, 0L), b = c(4L,3L, 1L, 2L, 1L, 5L, 2L, 2L), c = c(1L, 1L, 1L, 1L, 1L, 1L, 1L,1L), d = c(0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L), t = c(42L, 34L, 74L,39L, 47L, 8L, 36L, 39L), s = c(0L, 0L, 0L, 0L, 0L, 1L, 0L, 0L)), .Names = c("a", "b", "c", "d", "t", "s"), row.names = c(NA,8L), class = "data.frame") 
c<-c("a","b","c","d")

and the code

library(survival)
library(survminer)

plot <- function() {
    for (i in c) { 
        fit <- survfit(update(Surv(t,s)~., reformulate(i)), data=mydata)
        ggsurvplot(fit)
    }
}
plot()

When I copy/paste that into R I do not get any errors. You must be doing something different than the sample code you've posted.

MrFlick
  • 195,160
  • 17
  • 277
  • 295
  • Thanks but the code exists with the following error: Error in reformulate(i) : object 'i' not found – riz Sep 10 '16 at 06:44
  • Your example had `for (i in c)`. Did you not keep that part? How did you get an error about `SEX` when that's no where in your example? – MrFlick Sep 10 '16 at 14:20
  • Yes, I kept that for condition) as well. I tried with the complete version of the dataset. So, that error message – riz Sep 10 '16 at 14:44
  • I tested my answer again and it works. I've included the complete code block above. You should be able to copy/paste that into a new R session and verify it works. – MrFlick Sep 10 '16 at 15:01