R function; if input is not given, ask for it - r

I'm trying to write a function in R that takes two inputs as strings. If neither input is set, it asks for the inputs and then continues the function.
Input < - function(j,k){
if ((j==j)&&(k==k)){
j <- readline(prompt="Enter Input 1: ")
k <- readline(prompt="Enter Input 2: ")
Input(j,k)
}else if ((j=="<string here>")&&(k=="<string here>")){
....
}
}

I think the better way to structure your approach would be this, using optional arguments and testing to see if they are non-null before proceeding, though admittedly your posted question is very vague:
Input < - function(j=NA, k=NA) {
if (is.na(j) | is.na(k)){
j <- readline(prompt="Enter Input 1: ")
k <- readline(prompt="Enter Input 2: ")
Input(j, k)
} else if ((j == "<string here>") & (k == "<string here>")) {
....
}
}

Although I personally prefer the is.NA or is.NULL (as in #Forrest 's answer), this is an alternative with missing that might look simpler for someone starting now with R.
Input <- function(j, k) {
if (missing(j) | missing(k)){
j <- readline(prompt="Enter Input 1: ")
k <- readline(prompt="Enter Input 2: ")
Input(j, k)
} else if ((j == "<string here>") & (k == "<string here>")) {
....
}
}

I think it's simplest perhaps to put the readline code as the argument. The force commands force evaluation of that code at that point in the function. I don't think they're necessary but depending what else the function does, you may want to make sure that it's asking for j and k first instead of later; otherwise the code will be evaluated when it first needs to know what j and k are.
Input <- function(j = readline(prompt="Enter Input 1: "),
k = readline(prompt="Enter Input 2: ")) {
force(j)
force(k)
if ((j=="<string here>") && (k=="<string here>")) {
....
}
}

Related

confunsion in create if in R

I have a question how to make a IF
for (i in 1:12){
for (j in 1:12) {
if (i != j) {
var = x + b
}
else{ }
}}
"else" I need that when they are equal to continue with j + 1 example: if i = 4 and j = 4 then continue with j = 5 and continue counting until the end of j and continue the process of when i! = j
I think you don't understand what is going on in your code or you don't understand what for loops do. One "trick" you can do is to actually print what happens in your for loops so that you will have one idea of what is going on. You could also do this with a piece of paper.
As they already pointed you out, you don't need the else because the for already takes care of this.
for (i in 1:12){
print("-------------------------------")
valueI <- paste0("my i value is ",i)
print(valueI)
for (j in 1:12) {
valueJ <- paste0("my j value is ",j)
print(valueJ)
if (i != j) {
#var = x + b
diff <- paste0(i, " is different than ", j)
print(diff)
}
else{
}
}
}
This code is the same as yours and will generate a log that explains you what happens step from step, you could also use a debugger but seeing your struggles, better use this for now. What are you trying to calculate? I feel like you want to calculate the power of something...

Error in if (num < 0) { : missing value where TRUE/FALSE needed

y <- as.integer(readline(prompt ="Enter a number: "))
factorial = 1
if (y< 0){
print("Error")
} else if (y== 0)
{
print("1")
} else
{
for(i in 1:y) {
factorial = factorial * i
}
return(factorial)
}
wondering why this is giving:
Error in if (y< 0) { : missing value where TRUE/FALSE needed
is it cause the first line has data type NA_integer?
There are three possible ways to pass values to the if statement.
y <- 1
if (y > 0) print("more")
This one works as expected.
y <- 1:3
if (y > 0) print("ignores all but 1st element")
As the warning message will tell you, only the first element was used to evaluate it. You could use any or all to make this right.
y <- NA
if (y > 0) print("your error")
This case actually gives you your error. I would wager a bet that y is somehow NA. You will probably need to provide a reproducible example (with data and the whole shebang) if you'll want more assistance. Note also that it helps visually structure your code to improve readability.

In R, how to read multiple integers from user prompt?

I need to create a vector with multiple inputs (integers) from user.
The intent is to create a list and verify if it has a mode and where is its median.
I am using this code:
ReadVector <- function()
{
x <- 0
while(x<16) {
n <- readline(prompt="Input one integer: ")
return(as.integer(n))
VectorUser <- c(n)
x <- x+1
}
print(VectorUser)
}
ReadVector()
And I can only get one integer, I dont know if my mistake is in the while loop or(and) in the concatenate command after it. Can you help me?
Does this work for you?
ReadVector <- function()
{
x <- 0
myvector = vector()
while(x<16) {
n <- readline(prompt="Input one integer: ")
myvector = c(myvector,n)
x <- x+1
}
return (as.integer(myvector))
}
You need yo save your values in a vector, and keep it (without returning inside the loop), until you completed it.
Hope it helps
ff=function(){
d=c()
while (TRUE){
int = readline('ENTER to quit > ')
if(nchar(int)==0) {
if(length(d)>0)cat("The numbers you entered are:",d)
else(cat("You did not enter any number!!"));break}
else{
value=suppressWarnings(as.integer(int))
if(!is.na(value)){cat(value);d=c(d,value)} else cat(ran[sample(6,1)])
}}
ff()

Wait until user enter a value and based on that value run set of codes

I want to make a program in which user will be asked to enter the location and based on that location value it should run a particular set of codes. It should wait until user enter the value of location.
readinteger <- function()
{
n <- readline(prompt="Enter your location: ")
n <- as.integer(n)
if (is.na(n))
return(as.integer(n))
}
LC <- readinteger()
if ( LC== 1)
{
print(x)
}
else if ( LC == 2)
{
print(y)
}
else
print(z)
But here it proceeds to if loop directly and then ask to enter the location
This will work fine if you include the if statements to control printing in your readinteger function. That way, readline will behave as expected (wait for input from the user) and then automatically move on to the printing commands.
readinteger <- function()
{
n <- readline(prompt="Enter your location: ")
n <- as.integer(n)
x <- "You are at location one."
y <- "You are at location two."
z <- "You are lost."
if ( n == 1)
{
print(x)
}
else if ( n == 2)
{
print(y)
}
else
print(z)
}
readinteger()
You had a if (is.na(n)) in your code that wasn't doing anything, but my guess is you want to include a check to make sure the user has provided valid input. If so, you may find a while loop helpful, so the user can correct their input if there's an error. For example:
readinteger <- function()
{
n <- NULL
while( !is.integer(n) ){
n <- readline(prompt="Enter your location: ")
n <- try(suppressWarnings(as.integer(n)))
if( is.na(n) ) {
n <- NULL
message("\nYou must enter an integer. Please try again.")
}
}
x <- "You are at location one."
y <- "You are at location two."
z <- "You are lost."
if ( n == 1)
{
print(x)
}
else if ( n == 2)
{
print(y)
}
else
print(z)
}
readinteger()
Ok. I think it's got something to do with running the whole file at one go.
It will work if you run it in Rsudio and run one step at a time, i.e., interactively.
According to the documentation of ?readline : `In non-interactive use the result is as if the response was RETURN and the value is "". In which case, one solution is to call the function again, as shown here : http://www.rexamples.com/4/Reading%20user%20input
I am not 100% sure it works without hitch.
For a more complex solution to your problem , you can see this question: Make readline wait for input in R
(Note: I'm adding this as answer simply for he sake of formatting. It's not really an answer )

How to setup a recursive lapply for specific values ex.w[i] == n[i]?

Background
I'm developing a function that takes in a value for w between 1 and 3 and returns n values from one of 3 distributions.
The problem I am having is when n or w are not of length 1. So I've added 2 parameters nIsList and wIsList to create the functionality I want. The way I want this to work is as follows:
(Works as needed)
If nIsList ex( c(1,2,3) ) return a list equivalent to running consume(w,1), consume(w,2), consume(w,3)
(Works as needed)
If wIsList ex( c(1,2,3) ) return a list equivalent to running consume(1,n), consume(2,n), consume(3,n)
(Doesn't work as needed)
If nIsList ex(1,2,3) and wIsList ex(1,2,3)
return a list equivalent to running consume(1,1), consume(2,2), consume(3,3). Instead, I get a list equivalent to running [consume(1,1), consume(1,2), consume(1,3)], [consume(2,1), consume(2,2), consume(2,3)], [consume(3,1),consume(3,2), consume(3,3)]
I understand why I am getting the results I am getting. I just can't seem to figure out how to get the result I want. (As explained above)
Question
I want the function to provide a list for each element in w and n that is consume(w[i], n[i]) when wIsList & nIsList are True. Is there a way to do that using lapply?
The code:
library("triangle")
consume <- function(w, n=1, nIsList=F, wIsList=F){
if(!nIsList & !wIsList){
if(w==1){
return(rtriangle(n,0.3,0.8))
}else if(w==2){
return(rtriangle(n,0.7,1))
}else if(w==3){
return(rtriangle(n,0.9,2,1.3))
}
}
else if(nIsList & !wIsList){
return(sapply(n, consume, w=w))
}
else if(nIsList & wIsList){
return(lapply(n, consume, w=w, wIsList=T))
}
else if(!nIsList & wIsList){
return(lapply(w, consume, n))
}
}
Note: I am having trouble summarizing this question. If you have any suggestions for renaming it please let me know and I will do so.
Thanks to JPC's comment, using mapply does the trick. The new code is as follows:
consume <- function(w, n=1){
nIsList <- length(n) > 1 # Change based on JPC's second comment
wIsList <- length(w) > 1 # Change based on JPC's second comment
if(!nIsList & !wIsList){
if(w==1){
return(rtriangle(n,0.3,0.8))
}else if(w==2){
return(rtriangle(n,0.7,1))
}else if(w==3){
return(rtriangle(n,0.9,2,1.3))
}
}
else if(nIsList & !wIsList){
return(sapply(n, consume, w=w))
}
else if(nIsList & wIsList){
return(mapply(consume,w,n)) ## Updated portion
}
else if(!nIsList & wIsList){
return(lapply(w, consume, n))
}
}

Resources