3

同じ ID コードを持つ複数のエントリを評価し、一連の条件が満たされた場合に最後の行でセル値を分割する必要があるデータセットがあります。

Condtionals = その ID の最終行には action=="l" & time >60 があります。

この条件が満たされた場合、行アクション <- "e"、および時間 <- 60 を変更したいと思います。60 を超える時間は、新しく形成された下の行に配置する必要があります。新しい行の列の内容は、action=="l" & time==元の値 - 60) を除いて、親行と同じである必要があります。

サンプルデータセット

id <- c("12_1","12_1","12_1","12_2","12_2","12_2")
action <- c("l","d","l","l","d","l")
time <- c(15,45,90,20,30,61)
dtfrm <-data.frame(cbind(id,action,time))

データフレームのテスト

    id action time
1 12_1      l   15
2 12_1      d   45
3 12_1      l   90
4 12_2      l   20
5 12_2      d   30
6 12_2      l   61

変換されたデータフレームを次のようにしたい

    id action time
1 12_1      l   15
2 12_1      d   45
3 12_1      e   60
4 12_1      l   30
5 12_2      l   20
6 12_2      d   30
7 12_2      e   60
8 12_2      l    1

最終的には、より複雑な条件を評価する必要がありますが、単純なものから始めて、このデータ セットを正常に機能させるために必要な、より複雑な条件を段階的に進めようとしています。ありがとう。

4

2 に答える 2

2

少し複雑ですが、これでうまくいくはずです:

# fix the time column, it should be numeric
dtfrm[, "time"] <- as.numeric(as.character(dtfrm[, "time"]))

library(data.table)
DT <- data.table(cbind(dtfrm, rowid=seq(nrow(dtfrm))), key="id")

# identify which rows need modification
DT[, needsMod := FALSE]
DT[unique(DT[, "id", with=FALSE])
   ,  needsMod := {L <- length(action); (action[L] == "l" && time[L] > 60)  }
   , by=id
   , mult="last"]

# append new rows
DT <- setkey(rbind(DT, 
       DT[c(needsMod), list(id, action, time=time-60, rowid=rowid+1e-2, needsMod=!needsMod)]), 
       id, rowid)

# modify the identified rows
DT[c(needsMod), c("action", "time") := list("e", 60)]

# optionally remove added columns, though personally, I would keep some form of rowid
DT[ , c("needsMod", "rowid") := NULL]
DT

#      id action time
# 1: 12_1      l   15
# 2: 12_1      d   45
# 3: 12_1      e   60
# 4: 12_1      l   30
# 5: 12_2      l   20
# 6: 12_2      d   30
# 7: 12_2      e   60
# 8: 12_2      l    1
于 2013-04-01T22:46:04.123 に答える