0

我有一个函数(bobB)似乎陷入了一个while循环。当我点击转义并查看 warnings() 时,出现以下错误:

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

一些示例代码:

#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)
4

1 回答 1

0

好的,这是你的问题(我认为):

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

(gsimre$sitex[i])并且(gsimre$sitey[i])是因素,这意味着当您使用它们来索引某些东西时,它们会被解释为数字而不是字符。事实上:

gsimre$sitey
[1] Sp4
Levels: Sp2 Sp4  

Sp4 是第二个因子,其数值为 2,因此specfreq[(gsimre$sitey[i]),y]specfreq[2,2]0。

因此,这应该可以解决问题:

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

或者您在开始时将它们声明为字符串而不是因子,就像您为ssf但不是为gsim

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

因为这个错误yf等于 0,因此f=min(xf,yf)总是等于 0,因此你的无限循环。

PS:如果您希望函数返回它,则answer应该退出循环,即。whilee.

    }
answer
}

代替

    answer
    }
}
于 2012-06-21T11:42:48.533 回答