4

次のコマンドで取得したものと同様のデータ テーブルがあります。

dt <- data.table(
  time = 1:8,
  part = rep(c(1, 1, 2, 2), 2),
  type = rep(c('A', 'B'), 4),
  data = rep(c(runif(1), 0), 4))

基本的に、このようなテーブルには 2 つの異なるタイプのインスタンス (A または B) が含まれます。時間列には、リクエストが特定の部分に到着したとき、または特定の部分から離れたときのタイムスタンプが含まれています。インスタンス タイプが A の場合、タイムスタンプは到着時刻 (enter) を示し、タイプが B の場合、タイムスタンプは出発時刻 (exit) を示します。

   time part type      data
1:    1    1    A 0.5842668
2:    2    1    B 0.0000000
3:    3    2    A 0.5842668
4:    4    2    B 0.0000000
5:    5    1    A 0.5842668
6:    6    1    B 0.0000000
7:    7    2    A 0.5842668
8:    8    2    B 0.0000000

A インスタンスと B インスタンスをペアにして、次のデータ テーブルを取得したいと考えています。

   part data        enter.time exit.time
1:    1 0.4658239   1          2
2:    1 0.4658239   5          6
3:    2 0.4658239   3          4
4:    2 0.4658239   7          8

私は次のことを試しました:

pair.types <- function(x) {
  a.type <- x[type == 'A']
  b.type <- x[type == 'B']
  return(data.table(
      enter.time = a.type$time,
      exit.time = b.type$time,
      data = a.type$data))
}

dt[, c('enter.time', 'exit.time', 'data') := pair.types(.SD), by = list(part)]

しかし、それは私に次のことを与えますが、これはまさに私が望むものではありません:

   time part type      data enter.time exit.time
1:    1    1    A 0.3441592          1         2
2:    2    1    B 0.3441592          5         6
3:    3    2    A 0.3441592          3         4
4:    4    2    B 0.3441592          7         8
5:    5    1    A 0.3441592          1         2
6:    6    1    B 0.3441592          5         6
7:    7    2    A 0.3441592          3         4
8:    8    2    B 0.3441592          7         8

ちょっと近いですが、列「type」が保持されているため、一部の行が重複しています。おそらく、列「時間」と「タイプ」を削除してから、行の後半を削除してみてください。しかし、それがすべての場合にうまくいくかどうかはわかりません。この操作を行うためのより良い方法を学びたいと思います。

4

2 に答える 2

3

データがサンプル データのように見えると仮定します。

dt[, list(part = part[1],
          data = data[1],
          enter.time = time[1],
          exit.time = time[2]),
     by = as.integer((seq_len(nrow(dt)) + 1)/2)]
#    by = rep(seq(1, nrow(dt), 2), each = 2)]
#    ^^^ a slightly shorter and a little more readable alternative

アイデアは非常に単純です - 行を 2 つのグループにグループ化します (これがそのby部分です)。つまり、各グループは 1 つの A と 1 つの B になり、次に各グループで最初partと最初dataに取得し、次に開始時刻と終了時刻が最初と 2 番目になります。timeのそれぞれです。これは、手書きのロジックに従っている場合に、読みやすくするために行う方法です (仕組みについて少し知っていればdata.table)。

于 2013-04-22T21:23:10.930 に答える
2

別の方法:

setkey(dt, "type")
dt.out <- cbind(dt[J("A"), list(part, data, entry.time = time)][, type := NULL], 
      exit.time = dt[J("B"), list(time)]$time)
#    part      data entry.time exit.time
# 1:    1 0.1294204          1         2
# 2:    2 0.1294204          3         4
# 3:    1 0.1294204          5         6
# 4:    2 0.1294204          7         8

setkey(dt.out, "part")必要に応じて、同じ注文を取得することができます。


アイデア: あなたの問題は、私には単純な「再形成」の問題のように思えます。私がアプローチした方法は、最初にキー列を として作成することtypeです。これで、キー列の特定の値に対して data.table を次のようにサブセット化できますdt[J("A")]。これは全体を返しますdata.table。列の名前を変更したいので、次timeを使用してサブセット化する列を明示的に言及します。

dt[J("A"), list(part, data, entry.time = time)]

もちろん、これはtype削除する列 (= A) も返します。[, type := NULL]そのため、参照によって列を削除するために を追加しましたtype

これで最初の部分ができました。必要なのはexit.time. これは、次のように取得できます。

dt[J("B"), list(time)] # I don't name the column here

ただし、これによりdata.table、時間列だけが必要な場合が得られます。これには、次の方法でアクセスできます。

dt[J("B"), list(time)]$time

したがって、使用cbind中にこの列に名前を付けてexit.time、最終結果を次のように取得します。

cbind(dt[J("A"), list(part, data, entry.time = time)][, type := NULL], 
      exit.time = dt[J("B"), list(time)]$time)

お役に立てれば。

于 2013-04-22T21:29:22.670 に答える