簡體   English   中英

根據ID拆分時變變量的值序列

[英]Splitting the sequence of values of a time-varying variable, conditionally on id

在分析的數據管理步驟中,我遇到了以下問題。

實際上,每個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創建兩個新的變量集,以獲得:

   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我們有不同的(不重復)的記錄的有序序列tv ,而在dur1 - dur5我們的次數相應的不同的記錄存在於原始數據集dat

我真的不知道該如何進行。任何幫助將不勝感激。

應該這樣做:

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

這完全是基於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. 創建一個零的空單行矩陣。 我們已經知道我們需要10列。
    2. 存儲rle()的輸出,因為我們需要“值”和“長度”
    3. 使用基本子集將“值”插入矩陣的前五列,並將“長度”插入后五列。
    4. 添加您的列名
    5. 使用一些技巧將矩陣“擴展”到指定的行數,在這種情況下,行數與每組中的行數相同。
  3. do.call(rbind...將所有矩陣放在一起,按行綁定它們。

  4. cbind(dat...將原始data.frame綁定到步驟1至3的結果。

再次,從概念上講,這與Arun的答案非常相似-使用rle()可能正是您所缺少的。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM