2012-01-25 22 views
4

survfit()basehaz()を関数内に使用したいが、機能しません。あなたはこの問題を見てみることができますか?ご協力いただきありがとうございます。次のコードは、エラーにつながる:関数内の数式エラー

library(survival) 

n <- 50  # total sample size 
nclust <- 5 # number of clusters 
clusters <- rep(1:nclust,each=n/nclust) 
beta0 <- c(1,2) 
set.seed(13) 
#generate phmm data set 
Z <- cbind(Z1=sample(0:1,n,replace=TRUE), 
     Z2=sample(0:1,n,replace=TRUE), 
     Z3=sample(0:1,n,replace=TRUE)) 
b <- cbind(rep(rnorm(nclust),each=n/nclust),rep(rnorm(nclust),each=n/nclust)) 
Wb <- matrix(0,n,2) 
for(j in 1:2) Wb[,j] <- Z[,j]*b[,j] 
Wb <- apply(Wb,1,sum) 
T <- -log(runif(n,0,1))*exp(-Z[,c('Z1','Z2')]%*%beta0-Wb) 
C <- runif(n,0,1) 
time <- ifelse(T<C,T,C) 
event <- ifelse(T<=C,1,0) 
mean(event) 
phmmd <- data.frame(Z) 
phmmd$cluster <- clusters 
phmmd$time <- time 
phmmd$event <- event 

fmla <- as.formula("Surv(time, event) ~ Z1 + Z2") 

BaseFun <- function(x){ 
start.coxph <- coxph(x, phmmd) 

print(start.coxph) 

betahat <- start.coxph$coefficient 
print(betahat) 
print(333) 
print(survfit(start.coxph))                                                          
m <- basehaz(start.coxph) 
print(m) 
} 
BaseFun(fmla) 
Error in formula.default(object, env = baseenv()) : invalid formula 

しかし、以下の機能が動作します:

fit <- coxph(fmla, phmmd)  
basehaz(fit) 
+0

http://stackoverflow.com/q/10176524/210673も同じ問題であるように見えます。 – Aaron

答えて

5

それはスコープの問題です。 basehazの環境がある 注意:一方

environment(basehaz) 
<environment: namespace:survival> 

environment(BaseFun) 
<environment: R_GlobalEnv> 

は、したがって、それは、関数basehazは、関数内のローカル変数を見つけることができない理由です。

可能な解決策は、assignを使用して先頭にXを送信することである。

BaseFun <- function(x){ 

    assign('x',x,pos=.GlobalEnv) 

    start.coxph <- coxph(x, phmmd) 
    print(start.coxph) 

    betahat <- start.coxph$coefficient 
    print(betahat) 
    print(333) 
    print(survfit(start.coxph)) 

    m <- basehaz(start.coxph) 
    print(m) 
    rm(x) 

     } 
    BaseFun(fmla) 

他の解決策は、より直接的な環境を扱う関与してもよいです。

+0

ニースが見つかりました。地球環境に「m」を割り当てる特別な理由は何ですか? –

+0

@RomanLuštrik実際にはタイプミスではない理由はありません。それをキャッチするためのtxs。 – aatrujillob

+1

@AndresTありがとうございます。できます。 Terry Therneauは解を提供しました。生存ルーチンはモデル行列を再構築する必要があります。デフォルトでは、これはモデル式が最初に定義されたコンテキストで行われます。残念ながら、これは関数の外にあり、問題につながります。引数 "x"は外側の環境変数では不明です。 "解決策は、モデルフレームが保存され、生存するために再構成を行う必要がないように、"モデル=真 "をcoxph呼び出しに追加することです。 – moli

2

私は@ moliのコメントを@ aatrujillobの答えにフォローアップしています。彼らは役に立ちましたので、私がそれをどのように解決したのか、そしてrpartpartykitのパッケージで同様の問題を解決する方法を説明すると思っていました。

いくつかのおもちゃのデータ:

N <- 200 
data <- data.frame(X = rnorm(N),W = rbinom(N,1,0.5)) 
data <- within(data, expr = { 
    trtprob <- 0.4 + 0.08*X + 0.2*W -0.05*X*W 
    Trt <- rbinom(N, 1, trtprob) 
    outprob <- 0.55 + 0.03*X -0.1*W - 0.3*Trt 
    Outcome <- rbinom(N,1,outprob) 
    rm(outprob, trtprob) 
}) 

私はトレーニング(train_data)とテストセットにデータを分割し、train_dataに分類ツリーを訓練したいと思います。

ここでは、使用したい式と、次の例の問題があります。この式を定義すると、train_dataオブジェクトはまだ存在しません。

私の機能は、元の機能に似ています。再度、

badFunc <- function(data, my_formula){ 
    train_data <- data[1:100,] 
    ct_train <- rpart::rpart(
    data= train_data, 
    formula = my_formula, 
    method = "class") 
    ct_party <- partykit::as.party(ct_train) 
} 

この関数を実行しようとすると、OPのようなエラーが発生します。

library(rpart) 
library(partykit) 

bad_out <- badFunc(data=data, my_formula = my_formula) 
# Error in is.data.frame(data) : object 'train_data' not found 
# 10. is.data.frame(data) 
# 9. model.frame.default(formula = Trt ~ W + X, data = train_data, 
#   na.action = function (x) {Terms <- attr(x, "terms") ... 
# 8. stats::model.frame(formula = Trt ~ W + X, data = train_data, 
#   na.action = function (x) {Terms <- attr(x, "terms") ... 
# 7. eval(expr, envir, enclos) 
# 6. eval(mf, env) 
# 5. model.frame.rpart(obj) 
# 4. model.frame(obj) 
# 3. as.party.rpart(ct_train) 
# 2. partykit::as.party(ct_train) 
# 1. badFunc(data = data, my_formula = my_formula) 

print(bad_out) 
# Error in print(bad_out) : object 'bad_out' not found 

幸いにも、rpart()は、あなたがこれらの問題を解決するために、引数model=TRUEを指定することができるという点でcoxph()のようなものです。ここでもう一度、その余分な議論があります。 rpart()model引数の

goodFunc <- function(data, my_formula){ 
    train_data <- data[1:100,] 
    ct_train <- rpart::rpart(
    data= train_data, 
    ## This solved it for me 
    model=TRUE, 
    ## 
    formula = my_formula, 
    method = "class") 
    ct_party <- partykit::as.party(ct_train) 
} 
good_out <- goodFunc(data=data, my_formula = my_formula) 
print(good_out)  
# Model formula: 
# Trt ~ W + X 
# 
# Fitted party: 
# [1] root 
# | [2] X >= 1.59791: 0.143 (n = 7, err = 0.9) 
##### etc 

ドキュメント:彼らは常に自然(私には)ない方法でlexical scopingenvironmentsを使用するよう

model:

if logical: keep a copy of the model frame in the result? If the input value for model is a model frame (likely from an earlier call to the rpart function), then this frame is used rather than constructing new data.

式は注意が必要です。これらの2つのパッケージでmodel=TRUEでテリー・テレノーが私たちの生活を楽にしました!