0

我正在尝试用 重塑以下数据集reshape(),但没有太多结果。

起始数据集采用“宽”形式,每个 id 通过一行描述。该数据集旨在用于进行多态分析(生存分析的概括)。

在给定的总时间跨度内记录每个人。在此期间,受试者可能会经历许多状态之间的转换(为简单起见,让我们将可以访问的最大不同状态数固定为两个)。第一个访问状态是s1 = 1, 2, 3, 4。该人在该州停留dur1一段时间,同样适用于第二次访问的州s2

   id    cohort    s1     dur1     s2     dur2     
     1      1        3      4       2      5       
     2      0        1      4       4      3    

我想获得的长格式数据集是:

id    cohort    s    
1       1       3
1       1       3
1       1       3
1       1       3
1       1       2
1       1       2
1       1       2
1       1       2
1       1       2
2       0       1
2       0       1
2       0       1
2       0       1
2       0       4
2       0       4
2       0       4

在实践中,每个 id 都有dur1 + dur2行,并且s1融合s2在一个变量s中。

你将如何进行这种转变?另外,您将如何返回原始数据集“宽”形式?

非常感谢!

dat <- cbind(id=c(1,2), cohort=c(1, 0), s1=c(3, 1), dur1=c(4, 4), s2=c(2, 4), dur2=c(5, 3))
4

2 回答 2

3

您可以reshape()用于第一步,但随后您需要做更多的工作。此外,reshape()需要 adata.frame()作为其输入,但您的样本数据是一个矩阵。

以下是如何进行:

  1. reshape() your data from wide to long:

    dat2 <- reshape(data.frame(dat), direction = "long", 
                    idvar = c("id", "cohort"),
                    varying = 3:ncol(dat), sep = "")
    dat2
    #       id cohort time s dur
    # 1.1.1  1      1    1 3   4
    # 2.0.1  2      0    1 1   4
    # 1.1.2  1      1    2 2   5
    # 2.0.2  2      0    2 4   3
    
  2. "Expand" the resulting data.frame using rep()

    dat3 <- dat2[rep(seq_len(nrow(dat2)), dat2$dur), c("id", "cohort", "s")]
    dat3[order(dat3$id), ]
    #         id cohort s
    # 1.1.1    1      1 3
    # 1.1.1.1  1      1 3
    # 1.1.1.2  1      1 3
    # 1.1.1.3  1      1 3
    # 1.1.2    1      1 2
    # 1.1.2.1  1      1 2
    # 1.1.2.2  1      1 2
    # 1.1.2.3  1      1 2
    # 1.1.2.4  1      1 2
    # 2.0.1    2      0 1
    # 2.0.1.1  2      0 1
    # 2.0.1.2  2      0 1
    # 2.0.1.3  2      0 1
    # 2.0.2    2      0 4
    # 2.0.2.1  2      0 4
    # 2.0.2.2  2      0 4 
    

You can get rid of the funky row names too by using rownames(dat3) <- NULL.

Update: Retaining the ability to revert to the original form

In the example above, since we dropped the "time" and "dur" variables, it isn't possible to directly revert to the original dataset. If you feel this is something you would need to do, I suggest keeping those columns in and creating another data.frame with the subset of the columns that you need if required.

Here's how:

Use aggregate() to get back to "dat2":

aggregate(cbind(s, dur) ~ ., dat3, unique)
#   id cohort time s dur
# 1  2      0    1 1   4
# 2  1      1    1 3   4
# 3  2      0    2 4   3
# 4  1      1    2 2   5

Wrap reshape() around that to get back to "dat1". Here, in one step:

reshape(aggregate(cbind(s, dur) ~ ., dat3, unique), 
        direction = "wide", idvar = c("id", "cohort"))
#   id cohort s.1 dur.1 s.2 dur.2
# 1  2      0   1     4   4     3
# 2  1      1   3     4   2     5
于 2013-01-11T15:12:57.850 回答
1

可能有更好的方法,但这可能有效。

df <- read.table(text = '
   id    cohort    s1     dur1     s2     dur2     
     1      1        3      4       2      5       
     2      0        1      4       4      3',
header=TRUE)

hist <- matrix(0, nrow=2, ncol=9)
hist

for(i in 1:nrow(df)) {

hist[i,] <- c(rep(df[i,3], df[i,4]), rep(df[i,5], df[i,6]), rep(0, (9 - df[i,4] - df[i,6])))

}

hist

hist2 <- cbind(df[,1:2], hist)
colnames(hist2) <- c('id', 'cohort', paste('x', seq_along(1:9), sep=''))

library(reshape2)

hist3 <- melt(hist2, id.vars=c('id', 'cohort'), variable.name='x', value.name='state')

hist4 <- hist3[order(hist3$id, hist3$cohort),]
hist4

hist4 <- hist4[ , !names(hist4) %in% c("x")]

hist4 <- hist4[!(hist4[,2]==0 & hist4[,3]==0),]

给出:

   id cohort state
1   1      1     3
3   1      1     3
5   1      1     3
7   1      1     3
9   1      1     2
11  1      1     2
13  1      1     2
15  1      1     2
17  1      1     2
2   2      0     1
4   2      0     1
6   2      0     1
8   2      0     1
10  2      0     4
12  2      0     4
14  2      0     4

当然,如果每个 id 有两个以上的状态,则必须对其进行修改(如果您有两个以上的群组,则可能必须对其进行修改)。例如,我假设有 9 个样本周期,一个人可能处于以下状态序列:

1 3 2 4 3 4 1 1 2
于 2013-01-11T13:11:04.017 回答