How to handle variable not defined error in r - r

Is there a way to evade variable not defined error in r? For example the code below throws variable not defined error.
for(i in length(someList)){
print(someList[[i]])
}
Can I check if a variable exists first before executing the code above. A pseudocode would look like this:
if(someList exists){
for(i in length(someList)){
print(someList[[i]])
}
} else cat("The variable does not exist")

Are you looking for the exists function?
someList <- list(1,2,3)
if (exists("someListNot")){
for(i in length(someListNot)){
print(someListNot[[i]])
}
}
if (exists("someList")){
for(i in 1:length(someList)){
print(someList[[i]])
}
}

You can use the exists("myVariable") function to check existence.
Also make sure your loop is really looping! If you use for (i in length(variable) it will only use the last index of your variable instead of looping over it.
You code could look something like this:
if ( exits("myVariable")){
for(i in seq_len(length(someList))){
print(someList[[i]])
}
}

Related

Create a series of new folders in for loop in R

I have create a small script that passes a vector through a loop. In this loop I am using an if else statement to check if folder exists and if not to create the folder. However, I am getting error: Error in file.exists(i) : invalid 'file' argument. This has to due with file.exist(). I dont understand why this isnt ok. I check the man using help. Seems like this should be working.
folders<- c("RawData", "Output", "BCV", "DEplots", "DEtables", "PathwayOuts", "VolcanoPLots")
for(i in 1:length(folders)){
if (file.exists(i)){
cat(paste0(i, "already exists"))
} else {
cat(paste0(i, "does not exists"))
dir.create(i)
}
}
You are looping over an index (that is, 1:length(folders) is just the vector 1:7, not the values of the folders vector itself. The easiest solution is to loop over the vector itself:
for (i in folders) {
Or, if you still want to loop over the index:
for (i in 1:length(folders)) {
if (file.exists(folders[i])){
cat(paste0(folders[i], "already exists"))
}
else {
cat(paste0(folders[i], "does not exists"))
dir.create(folders[i])
}
}
A quick tip: if you are debugging a for-loop, the place to start is to add print(i) at the start of the loop. You would have immediately seen the problem: i was an integer, not the first value of the vector.

R: Iterating Over the List

I am trying to implement following algorithm in R:
Iterate(Cell: top)
While (top != null)
Print top.Value
top = top.Next
End While
End Iterate
Basically, given a list, the algorithm should break as soon as it hits 'null' even when the list is not over.
myls<-list('africa','america south','asia','antarctica','australasia',NULL,'europe','america north')
I had to add a for loop for using is.null() function, but following code is disaster and I need your help to fix it.
Cell <- function(top) {
#This algorithm examines every cell in the linked list, so if the list contains N cells,
#it has run time O(N).
for (i in 1:length(top)){
while(is.null(top[[i]]) !=TRUE){
print(top)
top = next(top)
}
}
}
You may run this function using:
Cell(myls)
You were close but there is no need to use for(...) in this
construction.
Cell <- function(top){
i = 1
while(i <= length(top) && !is.null(top[[i]])){
print(top[[i]])
i = i + 1
}
}
As you see I've added one extra condition to the while loop: i <= length(top) this is to make sure you don't go beyond the length of the
list in case there no null items.
However you can use a for loop with this construction:
Cell <- function(top){
for(i in 1:length(top)){
if(is.null(top[[i]])) break
print(top[[i]])
}
}
Alternatively you can use this code without a for/while construction:
myls[1:(which(sapply(myls, is.null))[1]-1)]
Check this out: It runs one by one for all the values in myls and prints them but If it encounters NULL value it breaks.
for (val in myls) {
if (is.null(val)){
break
}
print(val)
}
Let me know in case of any query.

R code does not work when called from function

HI i just started learning R and finding this problem to be really interesting where I just run a code directly without wrapping in a function it works but when I place it inside a function it doesn't work, What can be possible reason?
fill_column<-function(colName){
count <- 0
for(i in fg_data$particulars) {
count <- count +1
if(grepl(colName, i) && fg_data$value[count] > 0.0){
fg_data[,colName][count] <- as.numeric(fg_data$value[count])
} else {
fg_data[,colName][count] <- 'NA'
}
}
}
fill_column('volume')
Where I am creating new column named volume it this string exists in particulars column.
I have added a comment where solution given by another question does not work for me, Please look at my comment below.
Finally I got it working but reading another answer on SO, here is the solution:
fill_column <- function(colName){
count <- 0
for(i in fg_data$particulars) {
count <- count +1
if(grepl(colName, i) && fg_data$value[count] > 0.0){
fg_data[,colName][count] <- as.numeric(fg_data$value[count])
} else {
fg_data[,colName][count] <- 'NA'
}
}
return(fg_data)
}
fg_data = fill_column('volume')
Now reason, Usually in any language when we modify global object inside any function it reflects on global object immediately but in R we have to return the modified object from function and then assign it again to global object to see our changes. or another way for doing this is to assign local object from within the function to global context using envir=.GlobalEnv.

return list of dataframe from inside a function to apply rbind using do.call()

Below is a trimmed version of my script. I am hoping my function will return me a list per loop iteration, so that I can rbind all the list to form a new data frame, but when I am executing this script, I keep getting the error:
do.call("rbind", listofdfs) : object 'listofdfs' not found
Thank you all for your help.
library(DBI)
library(RPostgreSQL)
drv<- dbDriver("MyDataBase")
con<-dbConnect(drv,dbname="DB_Name",
host="DB_Location",port=number,user="MyName",password= "Password")
dates <- seq(as.Date(as.character(Sys.Date() - 33)), as.Date(as.character(Sys.Date() - 1)), by=1)
my_function<-function(dates){
listofdfs<-list()
for(i in 1:length(dates){
data<-dbGetQuery(con, sprintf("select X,Y,Z from TABLE where date>=date('%s')", dates[i])
data$newColumn<-mean(data$X)
listofdfs[[i]]<-data
}
return(listofdfs)
}
df<-do.call("rbind", listofdfs)
I have a small simplified example to refer, please refer to the dates variable from above
my_list_function<-function(dates){
for(i in 1:length(dates))
{
my_list<-list()
my_list[[i]]<-i
}
return(my_list) }
k<-do.call(rbind,my_list(dates))
View(k)
now running
do.call(rbind,my_list(dates))
returns error could not find function "my_list" and running do.call(rbind,my_list_function(dates)) works but is only giving 33.
Thanks again for help.
listofdfs is a variable that is declared within your function. Therefore it is not defined outside of its body.
but because it is returned by the function, you can access it by calling the function itself:
df<-do.call("rbind", my_function(dates))
Also on to make you small example work:
my_list_function<-function(dates){
my_list<-list()
for(i in 1:length(dates))
{
my_list[[i]]<-i
}
return(my_list)
}
k<-do.call(rbind,my_list_function(dates))

R:Creating container to store data in a function

I am trying to write a function that reads a vector of numbers element wise and then storing them into a container. This is meant as a practice before I code something with if conditions.
My approach has failed so far, as the function returns a null statement, instead of what I wanted. I tried writing it in script form and it it worked, but somehow it malfunctioned when written as a function.
Here's the code I used.
amieven<-function(x){
flag<-numeric()
for(i in 1:length(x)){
flag[i]=x[i]
}
}
The script version that worked fine looks like this:
flag<-numeric()
for (i in 1:length(x))
flag[i]=x[i]
Assuming your goal is to return the container called flag, then you simply need to specify flag as the return value.
amieven<-function(x){
flag<-numeric()
for(i in 1:length(x)){
flag[i]=x[i]
}
return(flag)
}
or simply
amieven<-function(x){
flag<-numeric()
for(i in 1:length(x)){
flag[i]=x[i]
}
flag
}

Resources