R cannot find an object within a loop

gianmarco

TS Contributor
#1
My R programming skill is quite basic I know, so be gentle!
I am having difficulties in understanding what I am doing wrong here. Upon running the function, R reports an error saying that it cannot find the object 'd'.
actually, the error is the following: Error in d[i, ] <<- rbind(res$eig[, 1]) : oggetto "d" non trovato. The last fit is in Italian, saying that the object "d" is not found.

The aim of the function is to calculate the Correspondence Analysis' eigenvalues for the three table's dimensions. This is done once on the input contingency table, and B times for randomized tables. 'd' is the object (actually, a dataframe) in which the eigenvalues are stored.

Below is the code for a small dataset, and for the function I have been working with. The function requires the 'FactoMineR' package.

Code:
mydata <- structure(list(none = c(4, 4, 25, 18, 10), light = c(2, 3, 10, 
24, 6), medium = c(3, 7, 12, 33, 7), heavy = c(2, 4, 4, 13, 2
)), .Names = c("none", "light", "medium", "heavy"), row.names = c("SM", 
"JM", "SE", "JE", "SC"), class = "data.frame")
Code:
test <- function(data,B=1000){
  options(scipen = 999)
  nIter <- B+1

  numb.dim.cols <- ncol(data) - 1

  numb.dim.rows <- nrow(data) - 1

  table_dim <- min(numb.dim.cols, numb.dim.rows) # dimensionality of the table

  d <- as.data.frame(matrix(nrow=nIter, ncol=table_dim)) # object where eigenvalues are stored

  res <- CA(data, graph=FALSE) # perform CA on the original table

  d[1,]<- rbind(res$eig[,1]) # save the 3 eigenvalues in the first row of 'd'

  for (i in 2:nIter){
    rand_table <- as.data.frame(r2dtable(1, apply(data, 1,sum), apply(data, 2, sum)))  # create a randomized table

    res <- CA(rand_table, graph=FALSE) # perform CA on the random table

    d[i,] <<- rbind(res$eig[,1]) # this SHOULD store the new eigenvalues into subsequent rows of the 'd' object

  }
}
 

Dason

Ambassador to the humans
#3
But you might just need to change
Code:
 d[i,] <<- rbind(res$eig[,1])
to
Code:
 d[i,] <- rbind(res$eig[,1])
 

gianmarco

TS Contributor
#4
Thank you Dason. CA is a command out from the FactoMineR Package.
Now, your suggestion worked. What if I want to make 'd' available outside the function?

Cheers
 

Dason

Ambassador to the humans
#5
return d from the function then. You shouldn't be using global assigns to return values from a function.
 

Dason

Ambassador to the humans
#7
Code:
test <- function(data,B=1000){
  options(scipen = 999)
  nIter <- B+1

  numb.dim.cols <- ncol(data) - 1

  numb.dim.rows <- nrow(data) - 1

  table_dim <- min(numb.dim.cols, numb.dim.rows) # dimensionality of the table

  d <- as.data.frame(matrix(nrow=nIter, ncol=table_dim)) # object where eigenvalues are stored

  res <- CA(data, graph=FALSE) # perform CA on the original table

  d[1,]<- rbind(res$eig[,1]) # save the 3 eigenvalues in the first row of 'd'

  for (i in 2:nIter){
    rand_table <- as.data.frame(r2dtable(1, apply(data, 1,sum), apply(data, 2, sum)))  # create a randomized table

    res <- CA(rand_table, graph=FALSE) # perform CA on the random table

    d[i,] <- rbind(res$eig[,1]) # this SHOULD store the new eigenvalues into subsequent rows of the 'd' object

  }

  return(d)
}
Then to use it you would use...
Code:
d <- test(mydata)
So test returns 'd' when it's done and then when you call the function you just need to store the result wherever you want.