TraMineR:从基于SPELL的序列数据中提取相等状态之间的事件

时间:2013-04-23 12:55:17

标签: r traminer

上下文

此问题涉及使用TraMineR包进行序列分析。该软件包提供时间序列(时间状态)到事件序列的自动转换(状态在时间之间的变化)。我的分析中经常出现的问题之一涉及区分等同状态之间的变化事件的选项。

问题特定示例

假设我们有一系列就业状况,例如:工作,失业,不活动,退休。分析侧重于职业转型,区分稳定过渡职业。各种过渡都是相关的,从工作到失业,从不工作到工作,还有(最重要的)从工作到工作

问题

对于TraMineR,当序列中的状态发生变化时,会发生事件。例如,受访者有3年的工作,然后有1年的失业:工作 - 工作 - 失业(假设年度间隔)。这是STS格式,表示及时的状态。但是,在SPELL格式中,我们还有其他信息,例如:

Status         Time1 Time2

Work           1     2
Work           2     3
Work           3     3
Unemployment   3     4

从上表中我们可以清楚地看到发生了两个工作到工作的转换事件(否则只会有一行:从1到3工作)。问题是是否有任何方便的方法可以根据这些数据从序列对象中提取事件对象。

数据

我的数据包含SPELL格式的工作相关受访者状态(状态,开始和结束时间),如下所示:

to.SO <- structure(list(ID = c(10, 11, 11, 12, 13, 13, 13, 13, 14, 14,     
         14, 14, 14, 14, 14, 14, 14, 15, 15, 15, 15, 15, 15, 15), status = c(1, 
         1, 1, 1, 1, 1, 1, 1, 2, 3, 1, 2, 3, 2, 3, 1, 1, 1, 3, 1, 3, 3,         
         1, 3), time1 = c(1, 1, 104, 1, 1, 60, 109, 121, 1, 42, 47, 54,         
         64, 72, 78, 85, 116, 1, 29, 39, 69, 74, 78, 88), time2 = c(125,        
         104, 125, 125, 60, 109, 121, 125, 42, 47, 54, 64, 72, 78, 85,          
         116, 125, 29, 39, 69, 74, 78, 88, 125)), .Names = c("ID", "status",    
         "time1", "time2"), row.names = 10:33, class = "data.frame") 

我尝试了什么

根据this post我必须首先将SPELL转换为STS,然后定义序列:

sts.data <- seqformat(data=to.SO,from="SPELL",to="STS",
                 id="ID",begin="time1",end="time2",status="status",
                 limit=125,process=FALSE)

sts.seq <- seqdef(sts.data,right="DEL")
alphabed <- c("Work","Study","Unemployed")
alphabet(sts.seq) <- alphabed

我需要的信息在此步骤中已经丢失,但在错误(请参阅链接)得到解决之前,没有其他办法。它仍然显示了我想要实现的目标:

sts.seqe <- seqecreate(sts.seq) # creating events
sts.seqe

我的结果

这里,前四个事件序列是相同的。如果你看一下SPELL数据(to.SO),很明显,id为11和13的受访者有多个工作到工作的过渡。在我的另一篇文章中,我通过将不同的状态归为job-1来解决这个问题。 ,工作-2等等。然而,这是一个不太理想的策略,因为它(1)爆发了使后续相异性分析变得困难的状态数量,并且(2)在职业生涯中的工作在理论上并不重要,仅就业状况就应该涵盖它。

感谢

我认为这超出了现有的包功能,但也许我错过了一些东西。提前感谢阅读这篇长篇文章(至少)并提出任何建议。

2 个答案:

答案 0 :(得分:1)

我们确实可以想象一个解决方案,可以根据您的建议从拼写数据中创建事件序列。 TraMineR暂时不提供此功能(但请参阅Matthias的解决方案)。

您在问题中已经提到的解决方法是将后续作业区分为job1job2,...

我知道这不太理想,但您可以使用此策略仅用于定义分配相同事件的事件序列,例如"start new job"从作业 i 到作业 i +1的每次转换。为此,您需要指定一个大小为 a x a 的矩阵(tmat),其中 a 是您的大小状态字母表,列在每个单元格中( i j ),从状态 i 转换到状态 j <时发生的事件/ em>的。例如,在行job1和列job2的交叉点,您将提供"start new job",因为从job2切换到job1是不可能的只会将相应的单元格留空。对角线上的单元格tmat( i,i )定义了状态序列在相应状态 i 中开始时的开始事件。 一旦定义了矩阵(tmat),给出了分配给每个可能转换的事件,就可以将事件序列对象创建为

seqe <- seqecreate(sts2.seq, tevent=tmat)

您仍然可以使用原始sts.seq进行状态序列分析,只需一个工作状态。

希望这有帮助。

答案 1 :(得分:1)

'seqecreate'接受不同类型的输入。其中之一是状态序列对象(由seqdef生成)。但您也可以通过提供TSE格式的数据来构建事件序列对象。为此,您应指定三个向量:id,timestamp和event。

可以将拼写格式视为TSE格式的数据(如果忽略句点结束)。 begin列给出了状态列中事件发生的时间。

因此,我们可以使用以下代码:

## Start by giving some labels to the status vector
to.SO$event <- factor(to.SO$status, levels=1:3, labels=c("Work","Study","Unemployed"))
## Now, we can build the event sequences using seqecreate
## You may want to use timestamp=(to.SO$time1-1) instead. Events sequences start at time=0
seqe <- seqecreate(id=to.SO$ID, timestamp=to.SO$time1, event=to.SO$event)
seqe

现在第四个个体有正确的事件序列

如果您想分析“工作&gt;工作”转换,则需要重新编码数据。

## New vector holding our recoded events
event2 <- as.character(to.SO$event)
## For each row in the TSE data
for(i in 2:nrow(to.SO)){
    if(to.SO[i-1, "ID"]==to.SO[i, "ID"]) {## If we have the same ID (individual)
        if(to.SO[i-1, "event"]=="Work"&& to.SO[i, "event"]=="Work"){ ##Check 
           event2[i] <- "Work>Work"
        }
    }
}
## More general case
event3 <- as.character(to.SO$event)
## For each row in the TSE data
for(i in 2:nrow(to.SO)){
    if(to.SO[i-1, "ID"]==to.SO[i, "ID"]) {## If we have the same ID (individual)
        event3[i] <- paste(to.SO[i-1, "event"], to.SO[i, "event"], sep=">")
    }
}

通过调整此代码,您可以指定您感兴趣的转换。

seqe2 <- seqecreate(id=to.SO$ID, timestamp=to.SO$time1-1, event=event2)
seqe2

OR

seqe3 <- seqecreate(id=to.SO$ID, timestamp=to.SO$time1-1, event=event3)
seqe3