1

I was wondering how I can modify the code below to repeat the function up to 7 times. I can not use replicate(7, func(f)) since I need a function which gives me some option to choose the number of repetitions. I mean, a function which asks me whether I want to continue or not.

suppose

speed<-cars$speed
dist<-cars$dist
level<-c(1:50)   
f<-data.frame(speed,dist,level)
plot(speed, dist, main="Milage vs. Car Weight", 
    xlab="Weight", ylab="Mileage", pch=18, col="blue")
text(speed, dist, row.names(f), cex=0.6, pos=4, col="red")

This is my function

func = function(A){
id.co1 <- identify(f$speed, f$dist,labels=row.names(f), n = 2, pos = TRUE,plot = TRUE)
xy <- f[c(id.co1$ind[1],id.co1$ind[2]),]
lines(xy, col="red", lwd=5)
lm(dist~speed, xy)
abline(coef(lm(dist~speed, xy)),col="blue") 
x.co1 <- f$speed[id.co1$ind[1]:id.co1$ind[2]]
y.co1 <- f$dist[id.co1$ind[1]:id.co1$ind[2]]
m.co1 <- lm(y.co1 ~ x.co1)
}
Marco
  • 13
  • 3
  • While it seems you have a reproducible example, `cars` is unknown. Try it yourself in an empty R script. – Parfait May 04 '17 at 01:59
  • @Parfait, run require(stats); require(graphics) then you will have access to cars data set. – Marco May 04 '17 at 02:17
  • Are you sure? Those are base packages and should already be available. Please update your code with all relevant `library` or `require` lines and object assignment. Test reproducibility in a clean, new R environment. See this often [cited post](http://stackoverflow.com/questions/5963269/how-to-make-a-great-r-reproducible-example). – Parfait May 04 '17 at 12:31
  • @Parfait `cars` is in the `datasets` package and gets attached automatically. I cannot reproduce your "`cars` is unknown either in RStudio or in a console. – Janna Maas May 04 '17 at 12:57
  • Yes, I can run this code, but I don't understand `func`'s `A` argument. It doesn't appear to be used anywhere in the function. – BLT May 04 '17 at 14:46
  • @BLT i kicked it out in my answer, it doesn't seem to have any purpose. – Janna Maas May 04 '17 at 16:56

1 Answers1

1

if i understand correctly, you want to specify how often to repeat execution of a function interactively, not programmatically. You can do this with readline:

I need a function which gives me some option to choose the number of repetitions

# some function
funcA <- function(){
 cat("i am funcA\n")
}
# some function that interactively repeats funcA a specified amount of times
doNTimesA <- function() {
  Ntimes <- readline("number of repeats: ")
  for (i in 1:Ntimes) funcA()
}
doNTimesA()

I mean, a function which asks me whether I want to continue or not

funcB <- function(){
  while (TRUE) {
  cat("i am funcB\n")
  continue <- readline("again? y/n: ")
  if (tolower(continue)=="n") break
  }
  cat("funcB is done")
}
funcB()

edit: for your specific case, you can wrap your function declaration in a while loop that asks you whether you want to continue, as in my example funcB above. updated where it also stores its output:

func <- function(){
#initiate an iteration counter and an outputlist
  counter <- 1
  output <- list()
#start an infinite loop
  while (TRUE) {
#do your thing       
    id.co1 <- identify(f$speed, f$dist,labels=row.names(f), n = 2, pos = TRUE,plot = TRUE)
    xy <- f[c(id.co1$ind[1],id.co1$ind[2]),]
    lines(xy, col="red", lwd=5)
    lm(dist~speed, xy)
    abline(coef(lm(dist~speed, xy)),col="blue") 
    x.co1 <- f$speed[id.co1$ind[1]:id.co1$ind[2]]
    y.co1 <- f$dist[id.co1$ind[1]:id.co1$ind[2]]
    m.co1 <- lm(y.co1 ~ x.co1)
#store the result at counter index in the outputlist
    output[[counter]] <- list(xco =x.co1, yco=y.co1, lm =m.co1)
    counter <- counter+1
#prompt for next iteration
    continue <- readline("again? y/n: ")
#break the loop if the answer is 'n' or 'N'
    if (tolower(continue)=="n") break

  }
#return your output
  output
}

What happens now is that after every iteration, the function asks if you want to rerun the function: continue <- readline("again? y/n: ") and checks whether you have answered N or n. You can add more checks on the answer if you like; if you answer anything but N or n now, the loop will run again.

If you run all <- func(), after you're done you can access each iterations' result using all[[1]], all[[2]], etc.

Please note that it's generally frowned upon to manipulate objects outside your function environment, so it would be cleaner to pull the initial plot generation into your function.

Janna Maas
  • 1,124
  • 10
  • 15
  • Thanks so much for your help, I am a little bit confused about this solution. I want to select different intervals (points) by mouse clicking. What I want is after selecting each two points and connecting them by a straight line, the system asked me whether I want to continue and choose another pair of points. if I say yes then I could select another two points and if I say not the system would give me the value of my last two selection. – Marco May 04 '17 at 12:50
  • func is a function which I made and I want to repeat it based on number of the times which I want (by answering yes or not to whether I want to continue or not) – Marco May 04 '17 at 12:50
  • the small example is to show how to go about adding a "do you want to continue" option to a function, or to add a "i want to specify how often i want to do this" option. – Janna Maas May 04 '17 at 13:04
  • added your specific function. – Janna Maas May 04 '17 at 13:12
  • @ Janna Maas, great, thanks so much, just the last question, how can I bring all the results from different repetitions *id.co1* in one matrix. – Marco May 04 '17 at 15:14
  • @ Janna Maas, thanks so much for your help. I am really grateful for that. I have another question which I will post it soon. It would be great if you could please provide some answer for that too. It would be similar to this post. – Marco May 04 '17 at 17:56
  • @ Janna Maas, could you please provide some answer for this question too http://stackoverflow.com/questions/43789852/modifying-the-code-deleting-a-line-from-the-plot – Marco May 04 '17 at 18:03