我有一个数据框中的大数据集。这是一个示例(为简洁起见,我还省略了几列协变量):
id week
1 5
1 7
1 8
1 9
1 10
1 11
1 14
1 15
1 16
1 17
1 18
2 3
2 5
2 6
2 7
2 9
2 10
2 11
2 14
2 15
2 16
2 17
2 18
2 20
2 22
….. …..
8 8
11 8
14 8
16 8
18 8
21 8
22 8
25 8
26 8
27 8
36 8
37 8
3 9
4 9
5 9
7 9
8 9
9 9
10 9
11 9
14 9
15 9
17 9
18 9
22 9
23 9
我正在对这些数据进行一些生存分析,我需要以多种方式操纵数据。
首先,我需要添加一个列"事件"除了每个id的最后一行之外的所有行都取值0。例如,对于id = 1,行中的1对应于第18周,而其他行中为0。然后,等等所有约。 3000 ids。 我曾尝试过分裂'和'子集'但是我遇到了将数据恢复到原始数据框架的问题。
其次,我需要一个时间'对于每个id,为第一个(最小)周值取值1的列,然后以与周列相同的增量向上计数。以下两点的一个例子如下,即我想要最终得到的结果。 :
id week event time
1 5 0 1
1 7 0 3
1 8 0 4
1 9 0 5
1 10 0 6
1 11 0 7
1 14 0 10
1 15 0 11
1 16 0 12
1 17 0 13
1 18 1 14
2 3 0 1
2 5 0 3
2 6 0 4
2 7 0 5
2 9 0 7
2 10 0 8
2 11 0 9
2 14 0 12
2 15 0 13
2 16 0 14
2 17 0 15
2 18 0 16
2 20 0 18
2 22 1 20
第三,我需要采用这个新的数据集并创建一些新的列:每个周的假人'期。我需要37周'虚拟列,单元格中的1对应于'周'行和周虚拟列。
id event d1 d2 d3 d4 d5 d6 d7 d8 d9 covariate
1 0 0 0 0 0 1 0 0 0 0 0.70
1 0 0 0 0 0 0 0 1 0 0 0.56
1 0 0 0 0 0 0 0 0 1 0 0.70
1 0 0 0 0 0 0 0 0 0 1 0.16
我一直在尝试很多东西,主要是在过去几天的前两点,我仍处于学习曲线的陡峭部分。虽然变得更好。任何想法/评论等?谢谢!
答案 0 :(得分:2)
我们可以使用data.table
library(data.table)
setDT(dfN)[order(id, week), c("event", "time") := list(+(1:.N==.N),
cumsum(c(1,diff(week)))) ,id]
dfN
# id week event time
# 1: 1 5 0 1
# 2: 1 7 0 3
# 3: 1 8 0 4
# 4: 1 9 0 5
# 5: 1 10 0 6
# 6: 1 11 0 7
# 7: 1 14 0 10
# 8: 1 15 0 11
# 9: 1 16 0 12
#10: 1 17 0 13
#11: 1 18 1 14
#12: 2 3 0 1
#13: 2 5 0 3
#14: 2 6 0 4
#15: 2 7 0 5
#16: 2 9 0 7
#17: 2 10 0 8
#18: 2 11 0 9
#19: 2 14 0 12
#20: 2 15 0 13
#21: 2 16 0 14
#22: 2 17 0 15
#23: 2 18 0 16
#24: 2 20 0 18
#25: 2 22 1 20
或者
setDT(dfN)[order(id, week), c("event", "time") := list(c(rep(0,.N-1), 1),
cumsum(c(1,diff(week)))) ,id]
对于问题的第三部分,我们可以使用dcast
dfN[, week:=factor(week, levels=1:37)]
dfN[, N:= 1:.N]
res <- dcast(dfN, N~week, value.var="time", length, drop=FALSE)[,
c("id", "event") := dfN[, c("id", "event"), with=FALSE]][]
res[1:4]
# N 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 id event
#1: 1 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0
#2: 2 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0
#3: 3 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0
#4: 4 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0
注意:协变量没有显示在示例数据
中dfN <- structure(list(id = c(1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L,
1L, 1L,
1L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L),
week = c(5L, 7L, 8L, 9L, 10L, 11L, 14L, 15L, 16L, 17L, 18L,
3L, 5L, 6L, 7L, 9L, 10L, 11L, 14L, 15L, 16L, 17L, 18L, 20L,
22L)), .Names = c("id", "week"), row.names = c(NA, -25L),
class = "data.frame")
答案 1 :(得分:1)
使用基数R:
> df$event<-0
> df[c(which(diff(df$id)!=0),nrow(df)),"event"]<-1
> df$time<-(unlist(sapply(split(df,df$id),function(d){ cumsum(c(1,diff(d$week))) })))
> df
id week event time
1 1 5 0 1
2 1 7 0 3
3 1 8 0 4
4 1 9 0 5
5 1 10 0 6
6 1 11 0 7
7 1 14 0 10
8 1 15 0 11
9 1 16 0 12
10 1 17 0 13
11 1 18 1 14
12 2 3 0 1
13 2 5 0 3
14 2 6 0 4
15 2 7 0 5
16 2 9 0 7
17 2 10 0 8
18 2 11 0 9
19 2 14 0 12
20 2 15 0 13
21 2 16 0 14
22 2 17 0 15
23 2 18 0 16
24 2 20 0 18
25 2 22 1 20
或者如果你想采用拆分编辑改革的方式:
do.call(rbind,lapply(split(df,df$id),function(x){
y<-cbind(x,event=0); y[nrow(x),ncol(x)+1]<-1;
z<-cbind(y,time=cumsum(c(1,diff(x$week)))); z }))
对于第三部分,如果您希望一直持续37周(对应于列&#39; d1&#39;到&#39; d37&#39;):
> result<-t(apply(df,1,function(x){
tmp<-rep(0,37); names(tmp)<-paste0("d",1:37);
tmp[x["week"]]=1; c(x["id"],x["event"], tmp) }))
> result
id event d1 d2 d3 d4 d5 d6 d7 d8 d9 d10 d11 d12 d13 d14 d15 d16 d17 d18
[1,] 1 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0
[2,] 1 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0
[3,] 1 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0
[4,] 1 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0
d19 d20 d21 d22 d23 d24 d25 d26 d27 d28 d29 d30 d31 d32 d33 d34 d35 d36
[1,] 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
[2,] 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
[3,] 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
[4,] 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
d37
[1,] 0
[2,] 0
[3,] 0
[4,] 0