0

I have a function (bobB) that seems to be getting stuck in a while loop. When I hit escape and look at warnings() I get the following error:

Warning message:
In min(xf, yf) : no non-missing arguments to min; returning Inf  

Some example code:

#I have the data: 

x<-"A03" 
y<-"A24"

sitex<-c("Sp1","Sp1","Sp3","Sp3")
sitey<-c("Sp2","Sp4","Sp2","Sp4")
gsim<-c(0.2,0.3,0.4,0.1)
gsim<-data.frame(sitex,sitey,gsim)

site<-c("A03","A03","A03","A03","A24","A24","A24","A24")
species<-c("Sp1","Sp1","Sp3","Sp4","Sp1","Sp1","Sp3","Sp4")
freq<-c(0.2,0.3,0.4,0.1,0.3,0.3,0,0.4)
ssf<-data.frame(site,species,freq,stringsAsFactors=FALSE)

#My function:  

bobB <- function (x, y, ssf, gsim) {

#*Step 1.* Create an empty matrix 'specfreq' to fill 

#Selects the species frequency data greater than 0 for the two sites being compared  

ssfx <- ssf[ssf$site == x & ssf$freq >0,]
ssfy <- ssf[ssf$site == y & ssf$freq >0,]

#pull out the species that are present at site x and/or site y using a merge,  
#this is    needed to create the initial empty matrix  

m<-(merge(ssfx,ssfy,all=TRUE))
species<-unique(m$species)

#Creates an empty matrix of the frequency of each species at site x and y  

 specfreq <- matrix(0, length(species), 2, dimnames=list(species,c(x,y)))

#*Step 2.* Fill empty matrix 'specfreq' with data from data.frame 'ssf'  

for(i in 1:nrow(ssf{specfreq[rownames(specfreq)==ssf[i,"species"],colnames(specfreq)==ssf[i,"site"]] <- ssf[i,"freq"]}

#*Step 3.* For species present at site x and y remove the minimum of the two from both  
#find minimum frequency for each species for site x and y  

a <- pmin(specfreq[,x], specfreq[,y])

#subtract 'a' from current 'specfreq'  

specfreq <- specfreq - a

#*Step 4.* Calulate variable B  

#Set answer to 0

answer <- 0

#while 'specfreq' contains data (i.e. is >0) keep doing the following  

while(sum(specfreq) > 1e-10) {

#Find species remaining at site x  

sx <- species[specfreq[,1] > 0]

#Find species remaining at site y  

sy <- species[specfreq[,2] > 0]     

#Pull out the gsim value for sx and sy

gsimre <-gsim[gsim$sitex %in% sx & gsim$sitey %in% sy,]

#determines the row containing the maximum value for remaining gsim and assigns it to i     

i <- which.max(gsimre$gsim)

#once the max gsim value has been found (i) we go back to the specfreq matrix and filter  
#out the frequency of the site x species associated with i   

xf <- specfreq[(gsimre$sitex[i]),x]

#and the frequency of the site y species associated with i  

yf <- specfreq[(gsimre$sitey[i]),y]

#The frequency of the species at site x associated with the greatest i is multiplied by i           

answer <- answer + xf * gsimre$gsim[i]

#Then take the minimum common frequency for the two species associated with i  

f <- min(xf,yf)

#Subtract theminimum  common frequency from both the site x and site y column  

specfreq[gsimre$sitex[i],x] <- specfreq[gsimre$sitex[i],x]-f
specfreq[gsimre$sitey[i],y] <- specfreq[gsimre$sitey[i],y]-f   
}
answer
}
bobB(x, y, ssf, gsim)
Paul Hiemstra
  • 59,984
  • 12
  • 142
  • 149
Elizabeth
  • 6,391
  • 17
  • 62
  • 90
  • Suggestions for debugging: http://stackoverflow.com/questions/1882734/what-is-your-favorite-r-debugging-trick/5156351#5156351 – Ari B. Friedman Jun 21 '12 at 11:07
  • 2
    I *might* take a look at this if you make it much easier for me to copy and paste your code into a clean session. So, for starters, change your commentary to be either embedded code comments, or remove it (i.e. give me a single code block that works). – Andrie Jun 21 '12 at 11:09
  • 2
    Why have you ignored the comments and answers from your previous post of this question? It's obvious that `xf` and `yf` are empty, so you need to learn to debug. Work backwards to see what the values of `x,y,gsimre$sitex[i]` etc are until you find your error. – Carl Witthoft Jun 21 '12 at 11:18
  • @Andrie Thanks. I have reformatted the question to be one chunk of code as suggested – Elizabeth Jun 21 '12 at 11:31
  • @Carl Witthoft I have not ignored the comments made to my question about the min function. I was simply taking the advice of some of the comments and stating the problem in its entirety. It is still unclear to me what the problem is. – Elizabeth Jun 21 '12 at 11:43

1 Answers1

0

Ok so here is your problem (I think):

xf <- specfreq[(gsimre$sitex[i]),x]
yf <- specfreq[(gsimre$sitey[i]),y]

(gsimre$sitex[i])and (gsimre$sitey[i])are factors which means that when you use them to index something there are interpreted as numeric and not as characters. And indeed:

gsimre$sitey
[1] Sp4
Levels: Sp2 Sp4  

Sp4, being the second factor, has a numerical value of 2, hence specfreq[(gsimre$sitey[i]),y] is specfreq[2,2] which is 0.

Hence, this should do the trick:

xf <- specfreq[as.character(gsimre$sitex[i]),x]
yf <- specfreq[as.character(gsimre$sitey[i]),y]

Or you declare them as being strings and not factors at the beginning, as you did for ssf but not for gsim:

gsim<-data.frame(sitex,sitey,gsim, stringsAsFactors=FALSE)

Because of this mistake yf was equal to 0 and therefore f=min(xf,yf)was always equal to 0, hence your endless loop.

P. S. : answer should be out of the while loop if you want the function to return it, i. e.

    }
answer
}

instead of

    answer
    }
}
plannapus
  • 18,529
  • 4
  • 72
  • 94
  • Thanks plannapus. That seems to have worked and I can now fun BobB. However, when I run the 'external function' which combined the functions bobA, bobB, and bobC I still get the error "In min(xf, yf) : no non-missing arguments to min; returning Inf". I will post this as a different question though. Thanks again! – Elizabeth Jun 21 '12 at 12:45