pdeli
pdeli

Reputation: 534

Merge 2 while statements in R

I have two separate while statements, however being interdependent I need to merge them. According to this stackoverflow answer this should be pretty straightforward. However, what I tried did not work.

Below the separated while statements (with comments):

library(svDialogs)
library(quantmod)


# List of data.frame names
loadedDataframes <- names(which(unlist(eapply(.GlobalEnv,is.data.frame))))


# ask user to enter a ticker
ticker <- toupper(dlgInput(paste("Enter a ticker (these are already loaded:", toString(stripExtension), ")"), "e.g., AAPL")$res)


# check if ticker already loaded as ```data.frame```
existsTicker <- exists(ticker)


# while loop until a not loaded data.frame ticker is typed
while (existsTicker == TRUE){

  # Ask ticker again
  ticker <- toupper(dlgInput(paste("Please enter a ticker that has not yet been loaded:", toString(stripExtension), ")"), "e.g., AAPL")$res)
  
  # Check if ticker exists and load value in existsTicker
  existsTicker <- exists(ticker)
}


# get some stock prices from default service
yahooSymbol <- getSymbols.yahoo(ticker, env = globalenv())


# Close an open internet connection
# If getSymbols.yahoo has an unknown ticker, it leaves connection to Yahoo! open
closeAllConnections()


# Check if yahooSymbol returned a character(0) and if true
# ask for an existing ticker at Yahoo! Finance
while (identical(yahooSymbol, character(0)) == TRUE) {

  # Ask for an existing ticker at Yahoo! Finance
  ticker <- toupper(dlgInput(paste("Please enter an existing ticker at Yahoo! Finance, except: ", toString(loadedDataframes), ")"))$res)
  
  # Check if ticker exists and load value in existsTicker
  yahooSymbol <- getSymbols.yahoo(ticker, env = globalenv())
  
}

Below is a tentative merger of the two while conditions as per mentioned stakoverflow post. However, the code does not seem to "react" (for lack of a better term) whatever the symbol (whether existing or not):

# Merge two conditions into one while loop
while (existsTicker == TRUE && identical(yahooSymbol, character(0)) == TRUE) {
  
  # Ask ticker again
  ticker <- toupper(dlgInput(paste("Please enter a ticker that has not yet been loaded:", toString(stripExtension), ")"), "e.g., AAPL")$res)
  
  # Check if ticker exists and load value in existsTicker
  existsTicker <- exists(ticker)
  
  # Check if ticker exists and load value in existsTicker
  yahooSymbol <- getSymbols.yahoo(ticker, env = globalenv())
  
}

Any help appreciated.


System used:

Upvotes: 0

Views: 55

Answers (1)

Christopher Belanger
Christopher Belanger

Reputation: 631

Here's a potential answer, which is a bit simplified to focus on the core logic.

The issue I saw is that with a while() loop you're checking conditions before getting vital user input and after executing commands that affect the global environment.

Instead, this code evaluates each piece after it's executed: first the user input to see if they give a ticker that's already been read, and second the response from Yahoo to see if it's valid.

# load packages
library(svDialogs)
library(quantmod)

# start a loop; we'll find out if we need to exit based on user feedback
while (TRUE) {
  # get a potential ticker value from the user
  ticker <- toupper(dlgInput("Please enter a ticker that has not yet been loaded:")$res)
  
  # if this value already exists in global environment, immediately go back to
  # the beginning of the loop
  if (exists(ticker)) next
  
  # check Yahoo to see if the ticker is valid and if so get the results
  yahooSymbol <- getSymbols.yahoo(ticker, env = globalenv())
  
  # if yahoo returned a response, exit the loop
  if (!identical(yahooSymbol, character(0))) break
}

Upvotes: 1

Related Questions