2

私の分析のデータ管理ステップで、次の問題に遭遇しました。

実際には、それぞれidが最大 5 回記録され、関心のある時変変数tv = 1, 2, 3, 4. 私のデータが次のとおりであるとします。

dat <- read.table(text = "

        id      tv    
        1       2
        1       2
        1       1
        1       4
        2       4
        2       1
        2       4
        3       1
        3       2
        3       3
        3       3
        3       2", 

    header=TRUE)  

私がする必要があるのはtv、取得するために、 から始まる変数の 2 つの新しいセットを作成することです。

   id     tv     tv1   tv2   tv3   tv4   tv5    dur1  dur2  dur3  dur4  dur5 
    1      2      2     1     4     0     0       2     1     1     0     0
    1      2      2     1     4     0     0       2     1     1     0     0
    1      1      2     1     4     0     0       2     1     1     0     0
    1      4      2     1     4     0     0       2     1     1     0     0
    2      4      4     1     4     0     0       1     1     1     0     0
    2      1      4     1     4     0     0       1     1     1     0     0
    2      4      4     1     4     0     0       1     1     1     0     0
    3      1      1     2     3     2     0       1     1     2     1     0
    3      2      1     2     3     2     0       1     1     2     1     0
    3      3      1     2     3     2     0       1     1     2     1     0
    3      3      1     2     3     2     0       1     1     2     1     0
    3      2      1     2     3     2     0       1     1     2     1     0

それぞれについてid、 には、tv1個別の(繰り返されない) レコードのtv5順序付けられたシーケンスがあり、 には、それぞれの個別のレコードが元のデータセットに存在する回数があります。tvdur1dur5dat

ここでの進め方が本当にわかりません..どんな助けでも大歓迎です。

4

2 に答える 2

3

これはそれを行う必要があります:

require(plyr)
dat <- structure(list(id = c(1L, 1L, 1L, 1L, 2L, 2L, 2L, 3L, 3L, 3L, 
         3L, 3L), tv = c(2L, 2L, 1L, 4L, 4L, 1L, 4L, 1L, 2L, 3L, 3L, 2L
         )), .Names = c("id", "tv"), class = "data.frame", row.names = c(NA, 
         -12L))

out <- ddply(dat, .(id), function(x) {
    this.rle <- rle(x$tv)

    val <- this.rle$values
    val <- c(val, rep(0, 5-length(val)))
    val <- matrix(rep(val,nrow(x)), byrow=T, nrow=nrow(x))
    val <- as.data.frame(val)
    names(val) <- paste("tv", 1:5, sep="")

    len <- this.rle$lengths
    len <- c(len, rep(0, 5-length(len)))
    len <- matrix(rep(len,nrow(x)), byrow=T, nrow=nrow(x))
    len <- as.data.frame(len)
    names(len) <- paste("dur", 1:5, sep="")
    cbind(data.frame(tv=x$tv), val, len)
})

> out
   id tv tv1 tv2 tv3 tv4 tv5 dur1 dur2 dur3 dur4 dur5
1   1  2   2   1   4   0   0    2    1    1    0    0
2   1  2   2   1   4   0   0    2    1    1    0    0
3   1  1   2   1   4   0   0    2    1    1    0    0
4   1  4   2   1   4   0   0    2    1    1    0    0
5   2  4   4   1   4   0   0    1    1    1    0    0
6   2  1   4   1   4   0   0    1    1    1    0    0
7   2  4   4   1   4   0   0    1    1    1    0    0
8   3  1   1   2   3   2   0    1    1    2    1    0
9   3  2   1   2   3   2   0    1    1    2    1    0
10  3  3   1   2   3   2   0    1    1    2    1    0
11  3  3   1   2   3   2   0    1    1    2    1    0
12  3  2   1   2   3   2   0    1    1    2    1    0
于 2013-01-13T13:08:40.627 に答える
2

これは、完全にベース R のソリューションです。@Arun の回答と非常に似ていますが、「plyr」を使用するよりも高速になる可能性があります。

out <- cbind(dat, do.call(
    rbind, 
    lapply(split(dat$tv, dat$id), function(x) {
        OUT <- matrix(0, ncol = 10, nrow = 1)
        T1 <- rle(x)
        OUT[1, seq_along(T1$values)] <- T1$values
        OUT[1, 6:(5+length(T1$lengths))] <- T1$lengths
        colnames(OUT) <- paste(rep(c("tv", "dur"), 
                                   each = 5), 1:5, sep ="")
        OUT[rep(1, length(x)), ]
    })))
out
#    id tv tv1 tv2 tv3 tv4 tv5 dur1 dur2 dur3 dur4 dur5
# 1   1  2   2   1   4   0   0    2    1    1    0    0
# 2   1  2   2   1   4   0   0    2    1    1    0    0
# 3   1  1   2   1   4   0   0    2    1    1    0    0
# 4   1  4   2   1   4   0   0    2    1    1    0    0
# 5   2  4   4   1   4   0   0    1    1    1    0    0
# 6   2  1   4   1   4   0   0    1    1    1    0    0
# 7   2  4   4   1   4   0   0    1    1    1    0    0
# 8   3  1   1   2   3   2   0    1    1    2    1    0
# 9   3  2   1   2   3   2   0    1    1    2    1    0
# 10  3  3   1   2   3   2   0    1    1    2    1    0
# 11  3  3   1   2   3   2   0    1    1    2    1    0
# 12  3  2   1   2   3   2   0    1    1    2    1    0

何が起こっているかの要約は次のとおりです。

  1. split(dat$tv, dat$id)「id」ごとに「tv」に値のリストを作成します。

  2. 以下の匿名関数を適用します。

    1. ゼロの空の 1 行行列を作成します。10列が必要であることはすでにわかっています。
    2. rle()「値」と「長さ」の両方が必要なため、出力を保存します
    3. 基本的なサブセット化を使用して、「値」を行列の最初の 5 列に挿入し、「長さ」を最後の 5 列として挿入します。
    4. 列名を追加します
    5. ちょっとしたトリックを使用して、行列を指定された行数に "拡張" します。この場合は、グループごとの行数と同じ行数です。
  3. do.call(rbind...すべての行列をまとめて、行ごとにバインドします。

  4. cbind(dat...data.frameオリジナルをステップ 1 から 3 の結果にバインドします。

繰り返しますが、概念的には、これは Arun の回答と非常によく似てrle()います。

于 2013-01-13T19:48:47.350 に答える