3

https://github.com/kmiddleton/rexamples/blob/master/qplot_survival.Rにあるggplot2とコードを使用してカプランマイヤー曲線を描画しようとしています。

別のデータベースにあるこのすばらしいコードで良い結果が得られました。ただし、この場合、次のエラーが発生します...データフレームに空の行があるかのように:

Error en if (nrow(layer_data) == 0) return() : argument is of length zero.

私の場合、データと関数のタイプが同じではないため、このタイプのエラーに関する以前の質問は私には役に立たないようです。

私はRを使用した統計分析にかなり慣れておらず、プログラミングのバックグラウンドがないので、これは私のデータの「ばかげたバグ」であるに違いないと思いますが、どこにあるのかわかりません…ggplot2は間違いなくプロットする行が見つかりません。手がかりや提案など、なんらかの形で私を助けていただけませんか。

これが私のデータと使用されたコードで、コンソールの準備ができています-私はknitrスクリプトでそれを試しました-。最後に、sessionInfoを投稿しました。

library(splines)
library(survival)
library(abind)
library(ggplot2)
library(grid)

acbi30(実際のデータ)というデータフレームを作成します。

mort28day <- c(1,0,1,0,0,0,0,1,0,0,0,1,1,0,1,0,0,1,0,1,1,1,1,0,1,1,1,0,0,1)
daysurv <- c(4,29,24,29,29,29,29,19,29,29,29,3,9,29,15,29,29,11,29,5,13,20,22,29,16,21,9,29,29,15)
levo <- c(0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,1,0,0,1,0,0,0,0,0,0,0,0,0)
acbi30 <- data.frame(mort28day, daysurv, levo)
save(acbi30, file="acbi30.rda")
acbi30

次に、次のコマンドを貼り付けて、ggplot2を使用して関数を作成します。

t.Surv <- Surv(acbi30$daysurv, acbi30$mort28day)
t.survfit <- survfit(t.Surv~1, data=acbi30)


#define custom function to create a survival data.frame#
createSurvivalFrame <- function(f.survfit){

#initialise frame variable#
f.frame <- NULL

#check if more then one strata#
if(length(names(f.survfit$strata)) == 0){

#create data.frame with data from survfit#
f.frame <- data.frame(time=f.survfit$time, n.risk=f.survfit$n.risk, n.event=f.survfit$n.event, n.censor = f.survfit
$n.censor, surv=f.survfit$surv, upper=f.survfit$upper, lower=f.survfit$lower)
#create first two rows (start at 1)#
f.start <- data.frame(time=c(0, f.frame$time[1]), n.risk=c(f.survfit$n, f.survfit$n), n.event=c(0,0),
n.censor=c(0,0), surv=c(1,1), upper=c(1,1), lower=c(1,1))
#add first row to dataset#
f.frame <- rbind(f.start, f.frame)
#remove temporary data#
rm(f.start)
}
else {
#create vector for strata identification#
f.strata <- NULL
for(f.i in 1:length(f.survfit$strata)){
#add vector for one strata according to number of rows of strata#
f.strata <- c(f.strata, rep(names(f.survfit$strata)[f.i], f.survfit$strata[f.i]))
}
#create data.frame with data from survfit (create column for strata)#
f.frame <- data.frame(time=f.survfit$time, n.risk=f.survfit$n.risk, n.event=f.survfit$n.event, n.censor = f.survfit
$n.censor, surv=f.survfit$surv, upper=f.survfit$upper, lower=f.survfit$lower, strata=factor(f.strata))
#remove temporary data#
rm(f.strata)
#create first two rows (start at 1) for each strata#
for(f.i in 1:length(f.survfit$strata)){
#take only subset for this strata from data#
f.subset <- subset(f.frame, strata==names(f.survfit$strata)[f.i])
#create first two rows (time: 0, time of first event)#
f.start <- data.frame(time=c(0, f.subset$time[1]), n.risk=rep(f.survfit[f.i]$n, 2), n.event=c(0,0),
n.censor=c(0,0), surv=c(1,1), upper=c(1,1), lower=c(1,1), strata=rep(names(f.survfit$strata)[f.i],
2))
#add first two rows to dataset#
f.frame <- rbind(f.start, f.frame)
#remove temporary data#
rm(f.start, f.subset)
}
#reorder data#
f.frame <- f.frame[order(f.frame$strata, f.frame$time), ]
#rename row.names#
rownames(f.frame) <- NULL
}
#return frame#
return(f.frame)
}


#define custom function to draw kaplan-meier curve with ggplot#
qplot_survival <- function(f.frame, f.CI="default", f.shape=3){
#use different plotting commands dependig whether or not strata's are given#
if("strata" %in% names(f.frame) == FALSE){
#confidence intervals are drawn if not specified otherwise#
if(f.CI=="default" | f.CI==TRUE ){
#create plot with 4 layers (first 3 layers only events, last layer only censored)#
#hint: censoring data for multiple censoring events at timepoint are overplotted#
#(unlike in plot.survfit in survival package)#
ggplot(data=f.frame) + geom_step(aes(x=time, y=surv), direction="hv") + geom_step(aes(x=time,
y=upper), directions="hv", linetype=2) + geom_step(aes(x=time,y=lower), direction="hv", linetype=2) +
geom_point(data=subset(f.frame, n.censor==1), aes(x=time, y=surv), shape=f.shape)
}
else {
#create plot without confidence intervals#
ggplot(data=f.frame) + geom_step(aes(x=time, y=surv), direction="hv") +
geom_point(data=subset(f.frame, n.censor==1), aes(x=time, y=surv), shape=f.shape)
}
}
else {
if(f.CI=="default" | f.CI==FALSE){
#without CI#
ggplot(data=f.frame, aes(group=strata, colour=strata)) + geom_step(aes(x=time, y=surv),
direction="hv") + geom_point(data=subset(f.frame, n.censor==1), aes(x=time, y=surv), shape=f.shape)
}
else {
#with CI (hint: use alpha for CI)#
ggplot(data=f.frame, aes(colour=strata, group=strata)) + geom_step(aes(x=time, y=surv),
direction="hv") + geom_step(aes(x=time, y=upper), directions="hv", linetype=2, alpha=0.5) +
geom_step(aes(x=time,y=lower), direction="hv", linetype=2, alpha=0.5) +
geom_point(data=subset(f.frame, n.censor==1), aes(x=time, y=surv), shape=f.shape)
}
}
}

グローバル生存曲線のプロット(95%CI):

エラーは発生しません。

# Kaplan-Meier plot, global survival (with CI)
t.survfit <- survfit(t.Surv~1, data=acbi30)
t.survframe <- createSurvivalFrame(t.survfit)
t.survfit
qplot_survival(t.survframe, TRUE, 20)

層化生存曲線のプロット:

上記のエラーが発生します:

# Kaplan-Meier plot, stratified survival
t.survfit2 <- survfit(t.Surv~levo, data=acbi30)
t.survframe2 <- createSurvivalFrame(t.survfit2)
t.survfit2
qplot_survival(t.survframe2, TRUE, 20)

ggplot2なしで結果をプロットする:

t.survframe2の構造は、空の行がなくても問題ないように思われるため、qplot_survivalがt.survframe2のデータを読み取る際の問題である必要があります。単純なプロットを作成してもエラーは返されません。

t.survframe2
plot(t.survfit2)

データフレームの問題はどこにありますか?作成された関数は他のデータセットではうまく機能しますが、このデータセットでは機能しません...

前もって感謝します、

マレビブ

セッション情報:

sessionInfo()

Rバージョン2.15.2(2012-10-26)プラットフォーム:i386-w64-mingw32 / i386(32ビット)

locale:

[1] LC_COLLATE=Spanish_Spain.1252  LC_CTYPE=Spanish_Spain.1252   
[3] LC_MONETARY=Spanish_Spain.1252 LC_NUMERIC=C                  
[5] LC_TIME=Spanish_Spain.1252    

attached base packages:
[1] grid      splines   stats     graphics  grDevices utils     datasets 
[8] methods   base     

other attached packages:
[1] ggplot2_0.9.3    abind_1.4-0      survival_2.36-14 knitr_0.8       

loaded via a namespace (and not attached):
 [1] colorspace_1.1-1   dichromat_1.2-4    digest_0.5.2      
 [4] evaluate_0.4.2     formatR_0.7        gtable_0.1.2      
 [7] labeling_0.1       MASS_7.3-22        munsell_0.4       
[10] plyr_1.8           proto_0.3-9.2      RColorBrewer_1.0-5
[13] reshape2_1.2.1     scales_0.2.3       stringr_0.6.1     
[16] tools_2.15.2    
4

2 に答える 2

2

qplot_survival()私はあなたの機能に少し美容整形をしました。主な問題は、 ;のdata =引数のサブセット条件にあるようです。geom_pointと の両方t.survframeで、得られた値 0、3、および 12t.survframe2のテーブル。サブセット条件を に変更することで、すべてのケースでプロットを取得することができました。のポイントもわからなかったので、デフォルトを TRUE に設定し、それに応じて if 条件を変更しました。n.censorn.censor > 0f.CI = "default"

qplot_survival <- function(f.frame, f.CI= TRUE, f.shape=3)
{
 # use different plotting commands depending whether 
 # or not strata are given#
if(!("strata" %in% names(f.frame)))
{
  #confidence intervals are drawn if not specified otherwise#
   if( isTRUE(f.CI) )
   {
      # create plot with 4 layers (first 3 layers only events, 
      # last layer only censored)#
      # hint: censoring data for multiple censoring events at 
      # timepoint are overplotted#
      # (unlike in plot.survfit in survival package)#
   ggplot(data=f.frame) + 
      geom_step(aes(x=time, y=surv), direction="hv") + 
      geom_step(aes(x=time, y=upper), direction ="hv", linetype=2) + 
      geom_step(aes(x=time,y=lower), direction="hv", linetype=2) +
      geom_point(data=subset(f.frame, n.censor > 0), 
                 aes(x=time, y=surv), shape=f.shape)
   } else {
  #create plot without confidence intervals#
   ggplot(data=f.frame) + 
      geom_step(aes(x=time, y=surv), direction="hv") +
      geom_point(data=subset(f.frame, n.censor > 0), 
                 aes(x=time, y=surv), shape=f.shape)
          }
} else {
  if( !(isTRUE(f.CI)) ){
#without CI#
  ggplot(data=f.frame, aes(group=strata, colour=strata)) + 
     geom_step(aes(x=time, y=surv), direction="hv") + 
     geom_point(data=subset(f.frame, n.censor > 0), 
                aes(x=time, y=surv), shape=f.shape)
} else {

#with CI (hint: use alpha for CI)#
  ggplot(data=f.frame, aes(x = time, colour=strata, group=strata)) + 
      geom_step(aes(y=surv), direction="hv") + 
      geom_step(aes(y=upper), direction="hv", 
                   linetype=2, alpha=0.5) +
      geom_step(aes(y=lower), direction="hv", 
                   linetype=2, alpha=0.5) +
      geom_point(data=subset(f.frame, n.censor > 0), 
                 aes(y=surv), shape=f.shape)
      }
   }
}

これらの変更を行った後、次のプロットはすべてうまくいきました。

qplot_survival(t.survframe2, TRUE, 20)
qplot_survival(t.survframe2, FALSE, 20)
qplot_survival(t.survframe, TRUE, 20)
qplot_survival(t.survframe, FALSE, 20)

いくつかのコメント:

  1. この場合のように、条件を満たすとゼロ行のデータ フレームが返されることがあるため、関数内でのサブセット化は危険な場合があります。geom_point()レイヤーが本当に必要かどうかを検討します。
  2. いくつかの場所でdirections = "hv"geom_step()通話がありました。引数は複数形ではなく、上記で変更されています。
  3. これはもう少し効率的に行うことができると思いますが、survfitオブジェクトから目的の列を抽出する1つの方法、たとえばt.survfit、次のようなものです:

(階層が存在する場合はコンプを展開します)

comps <- c(2:6, 8, 10);
t.fit <- as.data.frame(do.call(cbind, lapply(comps, function(j) t.survfit[[j]])))
names(t.fit) <- names(t.survfit)[comps]
于 2013-01-05T06:13:03.587 に答える
1

これは、データに打ち切り点がない場合も考慮した別のバージョンです (@Dennis のバージョンはその場合でも失敗します)。これは、おそらくデータフレーム全体にいくつの検閲ポイントがあるかを事前に格納する変数を作成し、それを再利用することで、より効率的にすることができます。

# define custom function to draw kaplan-meier curve with ggplot
qplot_survival <- function(f.frame, f.CI="default", f.shape=3){
  # use different plotting commands dependig whether or not strata's are given
  if("strata" %in% colnames(f.frame) == FALSE){
    # confidence intervals are drawn if not specified otherwise
    if(f.CI=="default" | f.CI==TRUE ){
      # create plot with 4 layers (first 3 layers only events, last layer only censored)
      # hint: censoring data for multiple censoring events at timepoint are overplotted



      # (unlike in plot.survfit in survival package)
      p <- ggplot(data=f.frame) + geom_step(aes(x=time, y=surv), direction="hv") + geom_step(aes(x=time, 
                                                                                            y=upper), directions="hv", linetype=2) + geom_step(aes(x=time,y=lower), direction="hv", linetype=2)
      if(nrow(subset(f.frame, n.censor > 0)) > 0){
        p+geom_point(data=subset(f.frame, n.censor > 0), aes(x=time, y=surv), shape=f.shape)
      }else{
        p
      }
    }
    else {
      # create plot without confidence intervalls
      p <- ggplot(data=f.frame) + geom_step(aes(x=time, y=surv), direction="hv")
      if(nrow(subset(f.frame, n.censor > 0)) > 0){
        p + geom_point(data=subset(f.frame, n.censor > 0), aes(x=time, y=surv), shape=f.shape)
      }else{
        p
      }
    }
  }
  else {
    if(f.CI=="default" | f.CI==FALSE){
      # without CI 
      p <- ggplot(data=f.frame, aes(group=strata, colour=strata)) + geom_step(aes(x=time, y=surv), 
                                                                         direction="hv") 
      if(nrow(subset(f.frame, n.censor > 0)) > 0){
        p +geom_point(data=subset(f.frame, n.censor > 0), aes(x=time, y=surv), shape=f.shape)
      }else{
        p
      }
    }
    else {
      # with CI (hint: use alpha for CI)
      p <- ggplot(data=f.frame, aes(colour=strata, group=strata)) + geom_step(aes(x=time, y=surv), 
                                                                         direction="hv") + geom_step(aes(x=time, y=upper), directions="hv", linetype=2, alpha=0.5) + 
        geom_step(aes(x=time,y=lower), direction="hv", linetype=2, alpha=0.5)
      if(nrow(subset(f.frame, n.censor > 0)) > 0){
        p + geom_point(data=subset(f.frame, n.censor > 0), aes(x=time, y=surv), shape=f.shape)
      }else{
        p
      }
    }
  }
}
于 2013-11-17T20:33:53.983 に答える