2

長い形式の巨大なデータ ファイルがあります。その一部を以下に示します。各 ID には複数の行を含めることができ、status は最終的なステータスです。ただし、時変共変量を使用して分析を行う必要があるため、2 つの新しい時間変数を作成し、状態変数を更新する必要があります。私はこれにしばらく苦労してきました.IDごとに最大4行ある可能性があるため、これを効率的に行う方法がわかりません. 時変変数はNUM.AFTER.DIAGです。それならNUM.AFTER.DIAG==0簡単で、どこでtime1=0time2=STATUSDATE. ただしNUM.AFTER.DIAG==1、新しい行を作成する必要がある場合は、どこtime1=0に、time2=DOB-DATE.DIAGそしてNUM.AFTER.DIAG=0確認する必要がありSTATUS="B"ます。2 番目の行はtime1=time2前の行から取得され、time2=STATUSDATE-DATE.DIAG-time1この列から。同様に、さらに行がある場合は、異なる行を互いに減算する必要があります。また、NUM.AFTER.DIAG==0 でも複数の行がある場合は、余分な行をすべて削除できます。

これに対する効率的な解決策のアイデアはありますか? ジョン・フォックスの展開コマンドを見てきましたが、すべての間隔が最初からワイド形式であると想定しています。

編集:要求されたテーブル。センサー変数については、「D」=イベント (死亡)

ここに画像の説明を入力

 structure(list(ID = c(187L, 258L, 265L, 278L, 281L, 281L, 283L, 
    283L, 284L, 291L, 292L, 292L, 297L, 299L, 305L, 305L, 311L, 311L, 
    319L, 319L, 319L, 322L, 322L, 329L, 329L, 333L, 333L, 333L, 334L, 
    334L), STATUS = c("D", "B", "B", "B", "B", "B", "D", "D", "B", 
    "B", "B", "B", "D", "D", "D", "D", "B", "B", "B", "B", "B", "D", 
    "D", "B", "B", "D", "D", "D", "D", "D"), STATUSDATE = structure(c(11153, 
    15034, 15034, 15034, 15034, 15034, 5005, 5005, 15034, 15034, 
    15034, 15034, 6374, 5005, 7562, 7562, 15034, 15034, 15034, 15034, 
    15034, 7743, 7743, 15034, 15034, 4670, 4670, 4670, 5218, 5218
    ), class = "Date"), DATE.DIAG = structure(c(4578, 4609, 4578, 
    4487, 4670, 4670, 4517, 4517, 4640, 4213, 4397, 4397, 4397, 4487, 
    4213, 4213, 4731, 4731, 4701, 4701, 4701, 4397, 4397, 4578, 4578, 
    4275, 4275, 4275, 4456, 4456), class = "Date"), DOB = structure(c(NA, 
    13010, NA, NA, -1082, -626, 73, 1353, 13679, NA, 1626, 3087, 
    -626, -200, 2814, 3757, 1930, 3787, 6740, 13528, 14167, 5462, 
    6557, 7865, 9235, -901, -504, -108, -535, -78), class = "Date"), 
        NUM.AFTER.DIAG = c(0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 
        0, 0, 0, 0, 0, 1, 2, 3, 1, 2, 1, 2, 0, 0, 0, 0, 0)), .Names = c("ID", 
    "STATUS", "STATUSDATE", "DATE.DIAG", "DOB", "NUM.AFTER.DIAG"), row.names = c(NA, 
    30L), class = "data.frame")

編集:おそらくあまり効率的ではありませんが、解決策を思いつきました。

  u1<-ddply(p,.(ID),function(x) {

  if (x$NUM.AFTER.DIAG==0){

    x$time1<-0
    x$time2<-x$STATUSDATE-x$DATE.DIAG
    x<-x[1,]

  }
  else {

      x<-rbind(x,x[1,])
      x<-x[order(x$DOB),]
      u<-max(x$NUM.AFTER.DIAG)
      x$NUM.AFTER.DIAG<-0:u
      x$time1[1]<-0
      x$time2[1:(u)]<-x$DOB[2:(u+1)]-x$DATE.DIAG[2:(u+1)]
      x$time2[u+1]<-x$STATUSDATE[u]-x$DATE.DIAG[u]
      x$time1[2:(u+1)]<-x$time2[1:u]
      x$STATUS[1:u]<-"B"
      }
  x
}
)
4

1 に答える 1

0

わかりました、試してみましたが、変換プロセスを完全に理解しているかどうかはわかりません。間違いがある場合はお知らせください。多くの個体が存在する場合、一般ddplyに ( の場合でも) は遅くなります.parallel = TRUE。これは主に、最終的にすべての個体のすべてのデータ セットをまとめてrbind(または) それらをまとめなければならず、多数のオブジェクトrbind.fillに対して永遠にかかるためです。data.frame

ここに提案がdat.origあります。おもちゃのデータセットはどこにありますか:

まず、タスクを 2 つに分割します: 1) NUM.AFTER.DIAG == 0 2)NUM.AFTER.DIAG == 1

1) NUM.AFTER.DIAG == 0ID が複数回発生する場合 (ID 333 など)、time2 の計算と最初の行の抽出を除いて、パート 1) で行うことはあまりないようです。

## erase multiple occurences
dat <- dat.orig[!(duplicated(dat.orig$ID) & dat.orig$NUM.AFTER.DIAG == 0), ]
dat0 <- dat[dat$NUM.AFTER.DIAG == 0, ]
dat0$time1 <- 0
dat0$time2 <- difftime(dat0$STATUSDATE, dat0$DATE.DIAG, unit = "days")
time.na <- is.na(dat0$DOB)
dat0$time1[time.na] <- dat0$time2[time.na] <- NA

> dat0
    ID STATUS STATUSDATE  DATE.DIAG        DOB NUM.AFTER.DIAG time1      time2
1  187      D 2000-07-15 1982-07-15       <NA>              0    NA    NA days
3  265      B 2011-03-01 1982-07-15       <NA>              0    NA    NA days
4  278      B 2011-03-01 1982-04-15       <NA>              0    NA    NA days
5  281      B 2011-03-01 1982-10-15 1967-01-15              0     0 10364 days
7  283      D 1983-09-15 1982-05-15 1970-03-15              0     0   488 days
10 291      B 2011-03-01 1981-07-15       <NA>              0    NA    NA days
11 292      B 2011-03-01 1982-01-15 1974-06-15              0     0 10637 days
13 297      D 1987-06-15 1982-01-15 1968-04-15              0     0  1977 days
14 299      D 1983-09-15 1982-04-15 1969-06-15              0     0   518 days
15 305      D 1990-09-15 1981-07-15 1977-09-15              0     0  3349 days
17 311      B 2011-03-01 1982-12-15 1975-04-15              0     0 10303 days
26 333      D 1982-10-15 1981-09-15 1967-07-15              0     0   395 days
29 334      D 1984-04-15 1982-03-15 1968-07-15              0     0   762 days

2) は少しトリッキーですが、実際に行う必要があるのは、もう 1 行を挿入して時間変数を計算することだけです。

## create subset with relevant observations
dat.unfold <- dat[dat$NUM.AFTER.DIAG != 0, ]
## compute time differences
time1 <- difftime(dat.unfold$DOB, dat.unfold$DATE.DIAG, unit = "days")
time1[time1 < 0] <- 0
time2 <- difftime(dat.unfold$STATUSDATE, dat.unfold$DATE.DIAG, unit = "days")

## calculate indices for individuals
n.obs <- daply(dat.unfold, .(ID), function(z) max(z$NUM.AFTER.DIAG) + 1)
df.new <- data.frame(ID = rep(unique(dat.unfold$ID), times = n.obs))
rle.new <- rle(df.new$ID)
ind.last <- cumsum(rle.new$lengths)
ind.first <- !duplicated(df.new$ID)
ind.first.w <- which(ind.first) 
ind.second <- ind.first.w + 1
ind2.to.last <- unlist(sapply(seq_along(ind.second), 
                function(z) ind.second[z]:ind.last[z]))

## insert time variables
df.new$time2 <- df.new$time1 <- NA
df.new$time1[ind.first] <- 0
df.new$time1[!ind.first] <- time1
df.new$time2[!ind.first] <- time2
df.new$time2[ind2.to.last - 1] <- time1

これは私に与えます:

> df.new
    ID time1 time2
1  258     0  8401
2  258  8401 10425
3  284     0  9039
4  284  9039 10394
5  319     0  2039
6  319  2039  8827
7  319  8827  9466
8  319  9466 10333
9  322     0  1065
10 322  1065  2160
11 322  2160  3346
12 329     0  3287
13 329  3287  4657
14 329  4657 10456

これは、STATUS変数と他の変数に対して同様の方法で機能するはずです。両方のステップが別々に機能している場合はrbind、最後に 1 つのステップを実行するだけです。

于 2012-12-31T03:15:49.020 に答える