2012-04-26 10 views
2

私は、各ステップでオブジェクトが作成される複数のステップを持つ関数を作成しています。特定のステップが失敗し(temp3)、前のステップオブジェクトを見つけることができません(エラー:オブジェクト 'temp2'が見つかりません)。なぜ私はよく似ているのですか?同じ構造で、以前に作成されたオブジェクトに続く各ステップが関数内でうまく動作します。そのコードを関数の外で実行すると(コードがうまくいくので)、debug()を使ってデータ(temp2)を作成していないステップが実際にローカルメモリに格納されていますオブジェクト "temp2")、しかし何らかの理由でRはそれを認識したり使用したりしていないようです。私は困惑している!たぶん、私は、Rがステップを評価してローカルメモリ内のオブジェクトを呼び出す方法を知りませんでしたか?私は間違った方法で関数を書くことに行きましたか?Rはオブジェクトをメモリに呼び出しません。

私はこの関数が奇妙なパッケージなどを呼び出すので、もっと使いたいと思ったら簡単に準備することができますが、私はRがオブジェクトをどのようにローカルメモリに割り当てるか誤解しています関数。同様のクエリはHow does R handle object in function call?ですが、実際には関数内に新しいオブジェクトを割り当てています。 助けてくれますか?返信で

glm.random<-function(df){ 
    reps=5 
    output<-matrix(NA, ncol=1, nrow=0) 
    while (length(output[,1])<reps) {  
     temp1 <- ddply(df,.(study_id),randomRows,1) 
     temp2 <- subset(temp1,select = c(continent,taxatype, metric,nullm, yi_pos)) 
     temp3 <- glmulti(yi_pos ~ ., data = temp2, family = gaussian(link = log), crit = aic, plotty = F, report = F)   
     temp4 <- noquote(paste(summary(temp3)$bestmodel[1])) 
     output<-rbind(output,temp4)  
     } 
    write.table(output, "output.glm.random1.txt", append=TRUE, sep="\t", quote=FALSE) 
    } 

:再び

こんにちは、

Andrie - 1)。だから、私はサブセットの使用を削除します(しかし、ここで不思議な結果は何を意味しますか?)。 2)。私は手元のデータではそれが難しいと思っていましたが、ここで私のコーディングアプローチを改善する必要があります。良いヒント!しかし、ここでは、そのことを確認するだけで作業しています - 私は、より多くの分析のためにその出力オブジェクトを使用する可能性が高いです。

ギャビン1)やります! 2 + 3)したがって、エラーはtemp1の作成(または呼び戻し)にあります。

以下は再生可能なコードです。それが役に立つなら、私が複製しようとしているアプローチはGibson et al。 2011 Nature 478:378。 (詳細な方法「一般化線形モデル」を参照)。 ?glmultiから

Thank you! 

    #rm(list = ls()) 
    library("plyr") 
    library("glmulti") 
    # random rows function 
    randomRows = function(df,n){ 
     return(df[sample(nrow(df),n),]) 
    } 
    # Dataframe example 
    study_id <- c(1,1,1,1,2,2,3,3,3,4) 
    continent <- c("AF","AF","AF","AF","AF","AF", "AS", "AS", "AS", "SA") 
    taxatype <- c("bird","bird","bird","mam","mam","arthro", "arthro", "arthro", "arthro", "arthro") 
    metric<- c("sppr","sppr","sppr","sppr","abund","abund", "abund", "abund", "abund", "abund") 
    extra.data<- c(34:43) 
    yi_pos<- runif(1:10) 
    df<- data.frame(study_id=study_id, continent=continent,metric=metric, taxatype=taxatype,extra.data = extra.data, yi_pos = yi_pos) 
    df 

    # Function. Goal:repeat x10000 (but here reps =5) (Select one random value per study_id, run glmulti{glmulti}, select best ranked model, concatenate to an output and export). 
    glm.random<-function(df){ 
     reps=5 
     output<-matrix(NA, ncol=1, nrow=0) 
     while (length(output[,1])<reps) { 

     temp1 <- ddply(df,.(study_id),randomRows,1) 
     temp3 <- glmulti(yi_pos ~ continent+taxatype+metric, data = temp1, family = gaussian(link = log), crit = aic, plotty = F, report = F)   
     temp4 <- noquote(paste(summary(temp3)$bestmodel[1])) 
     output<-rbind(output,temp4)  
     } 
     write.table(output, "output.glm.random1.txt", append=TRUE, sep="\t", quote=FALSE) 
    } 

    # run function to obtain error 
    glm.random(df) 

# debug(glm.random) 
# glm.random(df) 
# undebug(glm.random) 
+0

もっと良い再生可能な例を作成できる場合は、コードには間違ったものは何もありませんが、いくつかの警告フラグが表示されます。 1) 'サブセットを使用しないでください - これは対話的な使用のためだけに設計されており、予期しない結果につながる可能性があることが十分に文書化されています。私の推測では、あなたのサブセットのステートメントに何かが間違っているということです。 2)必要な反復回数を事前に知っている場合は、whileを使用しないでください。代わりに 'lapply'のようなものを使用してください。 3)あなたが本当に持っていなければ、appendモードで 'write.table'を使わないでください。これによりファイルシステムの待ち時間の問題が発生する可能性があります。 – Andrie

+0

ありがとうAndrie。私はあなたの提案をまず試してみましょう、そして、私は例を挙げてあなたに戻ってきます。私はnullモデルを実行するために教えられてきたものだと思いますが、lapplyはちょうどビジネスになるかもしれません... – Bernard

+1

いくつかの事柄:i)決してループの結果オブジェクトを展開するのと同じように、 'rbind()'を使用しないでください。あなたは 'reps'行があることを知っていますので、' output [i、] < - temp4'を使って 'for(i in seq_len(reps))'ループを使って多くの行を割り当てます。次に、 'try()'で4つの 'tempX'生成呼び出しをそれぞれラップします。これにより、エラーは検出されますが、ループは続行されます。三番;エラーが出たら、 'traceback()'を実行して、何がエラーを投げたのかを見てください。その後、 'options(error =" recover ")'を実行してコードを再実行します。エラーがスローされると、デバッガにドロップされ、何がうまくいかないかを見ることができます。 –

答えて

2

If [the argument data is] not specified, glmulti will try to find the data in the environment of the formula, from the fitted model passed as y argument, or from the global environment.

しかし、あなたが指定したときdata = temp1glmultiは明らかに、このオブジェクトのために地球環境に見えます

。そのため、あなたは(私は物事を試してみてチェックして名前とオブジェクトを保つために少しと改名しました)地球環境へのあなたのランダムに選択されたデータを割り当てる必要があります。

glm.random2<-function(df){ 
    reps=5 
    output<-matrix(NA, ncol=1, nrow=0) 
    while (length(output[,1])<reps) { 
## Here things are different 
    temp2 <- ddply(df,.(study_id),randomRows,1) 
    names(temp2)[2]<-"cOntinent" 
    assign("temp1",temp2,envir=.GlobalEnv) 
## Note the slightly modified formula, to check whether 
## gmulti looks for terms in temp1 or simply as named objects in the environment 
## It looks like the former, which is good. 
    temp3 <- glmulti(yi_pos ~ cOntinent+taxatype+metric, data = temp1, 
     family = gaussian(link = log), crit = aic, plotty = F, report = F)   
    temp4 <- noquote(paste(summary(temp3)$bestmodel[1])) 
    output<-rbind(output,temp4) 
## Remove the object temp1 from the global environment 
    rm(temp1,envir=.GlobalEnv) 
    } 
    write.table(output, "output.glm.random1.txt", append=TRUE, sep="\t", quote=FALSE) 
} 

# run function - no error for me! 
glm.random2(df) 

あなたは、パッケージのメンテナに確認することをお勧めしますこれがglmultiの意図する方法であるかどうかを確認してください。

+0

ああ!ありがとう、私はあなたがそこで何をしたのかを見ています - 関数を呼び戻そうとしている場所にオブジェクトを割り当てることは、そのトリックです。これは即時の問題を解決するように見えますが、私は上のコメントが私のコーディング自体がいくつかの考えを必要としていることを示していると思います。 – Bernard