简体   繁体   中英

Strategies for more efficient and faster way of printing values in console output in R

Guys Thank you for taking some time in the post. I wanted to ask for general strategies to improve speeding up the computation as well as speeding up the print process of some values in the console window while looping very simple computations.

For instance, I have made a little lottery simulation code. Below code will generate the winning 6 numbers from 1 to 49 first. And then it continues to draw 6 numbers again seven times at a time, until they match the winning number.

It will display 7 draws and iteration (which is the number of draws) in one line until they match the winning number.

Lottery = function(computetime=FALSE){

  # winning numbers
  sixnumber = sample(1:49, 6, replace=FALSE)


  getfirst1 = getfirst2 = getfirst3 = getfirst4 = getfirst5 = getfirst6 = getfirst7 = 0
  iter=0

  if(computetime==FALSE){


  # loop until we have match winning number from 7 draws  
  while(! 6 %in% c(getfirst1, getfirst2, getfirst3, getfirst4, getfirst5, getfirst6, getfirst7)){
  iter=iter+7
  draw1 = sample(1:49, 6, replace=FALSE)
  draw2 = sample(1:49, 6, replace=FALSE)
  draw3 = sample(1:49, 6, replace=FALSE)
  draw4 = sample(1:49, 6, replace=FALSE)
  draw5 = sample(1:49, 6, replace=FALSE)
  draw6 = sample(1:49, 6, replace=FALSE)
  draw7 = sample(1:49, 6, replace=FALSE)

  # added for line to be arranged consistantly by formatting the numbers in each draw
  draw1[draw1<10] = paste0(0,draw1[draw1<10])
  draw2[draw2<10] = paste0(0,draw2[draw2<10])
  draw3[draw3<10] = paste0(0,draw3[draw3<10])
  draw4[draw4<10] = paste0(0,draw4[draw4<10])
  draw5[draw5<10] = paste0(0,draw5[draw5<10])
  draw6[draw6<10] = paste0(0,draw6[draw6<10])
  draw7[draw7<10] = paste0(0,draw7[draw7<10])

  # sum of the matching numbers in each draw
  getfirst1 = sum(sixnumber %in% draw1)
  getfirst2 = sum(sixnumber %in% draw2)
  getfirst3 = sum(sixnumber %in% draw3)
  getfirst4 = sum(sixnumber %in% draw4)
  getfirst5 = sum(sixnumber %in% draw5)
  getfirst6 = sum(sixnumber %in% draw6)
  getfirst7 = sum(sixnumber %in% draw7)

  # Print out in console
  cat(draw1, " ", draw2, " ", draw3, " ", draw4, " ", draw5, " " , draw6, " " , draw7, "   ", iter, "\n")

  # without Sys.sleep, printing process will be slowed down and get lagged
  Sys.sleep(time=0.0001)
  }
  return(sixnumber)

  }else{

    # This part will test the time until 3500 draws
    a=Sys.time()
    while(iter != 3500){
      iter=iter+7
      draw1 = sample(1:49, 6, replace=FALSE)
      draw2 = sample(1:49, 6, replace=FALSE)
      draw3 = sample(1:49, 6, replace=FALSE)
      draw4 = sample(1:49, 6, replace=FALSE)
      draw5 = sample(1:49, 6, replace=FALSE)
      draw6 = sample(1:49, 6, replace=FALSE)
      draw7 = sample(1:49, 6, replace=FALSE)

      draw1[draw1<10] = paste0(0,draw1[draw1<10])
      draw2[draw2<10] = paste0(0,draw2[draw2<10])
      draw3[draw3<10] = paste0(0,draw3[draw3<10])
      draw4[draw4<10] = paste0(0,draw4[draw4<10])
      draw5[draw5<10] = paste0(0,draw5[draw5<10])
      draw6[draw6<10] = paste0(0,draw6[draw6<10])
      draw7[draw7<10] = paste0(0,draw7[draw7<10])

      getfirst1 = sum(sixnumber %in% draw1)
      getfirst2 = sum(sixnumber %in% draw2)
      getfirst3 = sum(sixnumber %in% draw3)
      getfirst4 = sum(sixnumber %in% draw4)
      getfirst5 = sum(sixnumber %in% draw5)
      getfirst6 = sum(sixnumber %in% draw6)
      getfirst7 = sum(sixnumber %in% draw7)

      cat(draw1, " ", draw2, " ", draw3, " ", draw4, " ", draw5, " " , draw6, " " , draw7, "   ", iter, "\n")
      Sys.sleep(time=0.0001)
    }
    b=Sys.time()
    cat(b-a, "Seonds for 3500 draws")
  }  

}


Lottery(computetime = TRUE)

I wanted to get some general tips on how to speed up the

1) computations on Sampling 6 numbers seven times at a time

2) Fastest and the most smooth way of printing out those seven draws and iteration one line at a time. ( for example, without Sys.sleep() function or current setting Sys.sleep(0.0001), console prints out lines with lag after like 30 seconds of running the function. I want to know how to avoid this lagging in printing process. )

Purpose of this post is to improve my efficiency and understand more of printing console process in R.

Thank you so much!

This cuts down computation time for 3500 draws from around 9 seconds to around 1.5 seconds:

Lottery = function(computetime=FALSE, seed = 1){
  set.seed(seed)
  # winning numbers
  sixnumber = sample(1:49, 6, replace=FALSE)

  getfirst <- as.list(rep(0, 7))
  iter=0

  if(computetime==FALSE){


    # loop until we have match winning number from 7 draws  
    while(!any(unlist(getfirst) == 6)){
      iter=iter+7
      draw <- lapply(1:7, function(x) sample(1:49, 6))

      # sum of the matching numbers in each draw
      getfirst <- lapply(draw, function(x) sum(sixnumber %in% x))

      # Print out in console
      draw <- lapply(draw, function(x) {x[x < 10] <- paste0(0, x[x < 10]); x})
      cat(sapply(draw, paste, collapse = " "), sep = "\n")

      # without Sys.sleep, printing process will be slowed down and get lagged
      Sys.sleep(time=0.0001)
    }
    return(sixnumber)

  }else{

    # This part will test the time until 3500 draws
    a=Sys.time()
    while(iter != 3500){
      iter=iter+7
      draw <- lapply(1:7, function(x) sample(1:49, 6))

      getfirst <- lapply(draw, function(x) sum(sixnumber %in% x))

      draw <- lapply(draw, function(x) {x[x < 10] <- paste0(0, x[x < 10]); x})
      cat(sapply(draw, paste, collapse = " "), sep = "\n")

      Sys.sleep(time=0.0001)
    }
    b=Sys.time()
    cat(b-a, "Seconds for 3500 draws")
  }  

}

We use lists to be able to loop efficiently with lapply and sapply , therefore avoiding the need to do every step seven times. I've also added the option to set a specific seed for reproducability.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM