我正在尝试创建基于其他数据集的条件的变量。我有两个数据集,A
和B
。
A
是患者随时间变化的状态寄存器。它是按天注册的。B
是对患者是否接受治疗的计划。
我想创建一个变量,表示患者是否按计划在A数据集中接受了治疗,即B数据集。
例如,我有3个病人,"X",“Y”和"Z“。
start
是观察开始的日子,stop
是观察结束的日子。
数据集A
如下。
A<-data.frame(ID=c(rep("X",15),rep("Y",10),rep("Z",20)),
start=c(seq(0,14),seq(0,9),seq(0,19)),
stop=c(seq(1,15),seq(1,10),seq(1,20)))
head(A,15)
ID start stop
1 X 0 1
2 X 1 2
3 X 2 3
4 X 3 4
5 X 4 5
6 X 5 6
7 X 6 7
8 X 7 8
9 X 8 9
10 X 9 10
11 X 10 11
12 X 11 12
13 X 12 13
14 X 13 14
15 X 14 15
在这个数据中,X被观察到从寄存器开始到15天。onset
是治疗开始的日子,end
是治疗结束的日子。
B
是治疗计划
B<-data.frame(ID=c(rep("X",3),rep("Y",2),rep("Z",4)),
onset=c(seq(0,10,by=5),seq(0,5,by=5),seq(0,15,by=5)),
end=c(seq(5,15,by=5),seq(5,10,by=5),seq(5,20,by=5)),
treat=c(1,0,1,1,1,0,0,1,1))
head(B,3)
ID onset end treat
1 X 0 5 1
2 X 5 10 0
3 X 10 15 1
所以,X接受了治疗,直到5天。5天后,X未接受治疗,10天后,X再次接受治疗。因此,A将是
head(A,15)
ID start stop treat
1 X 0 1 1
2 X 1 2 1
3 X 2 3 1
4 X 3 4 1
5 X 4 5 1
6 X 5 6 0
7 X 6 7 0
8 X 7 8 0
9 X 8 9 0
10 X 9 10 0
11 X 10 11 1
12 X 11 12 1
13 X 12 13 1
14 X 13 14 1
15 X 14 15 1
我尝试了带有mutate
函数的dplyr
包。
A%>%mutate(
treat=
case_when(
ID==B$ID & B$onset <= start & start < B$end ~ B$treat,
TRUE~0)
但它返回了错误。因为两个数据集的行数不相等。
如何解决这个问题?
发布于 2020-04-24 11:24:44
我们可以使用来自data.table
的非等联接
library(data.table)
setDT(A)[B, treat := treat, on = .(ID, start >= onset, stop <= end)]
head(A, 15)
# ID start stop treat
# 1: X 0 1 1
# 2: X 1 2 1
# 3: X 2 3 1
# 4: X 3 4 1
# 5: X 4 5 1
# 6: X 5 6 0
# 7: X 6 7 0
# 8: X 7 8 0
# 9: X 8 9 0
#10: X 9 10 0
#11: X 10 11 1
#12: X 11 12 1
#13: X 12 13 1
#14: X 13 14 1
#15: X 14 15 1
发布于 2020-04-24 11:32:03
A_merged <- left_join(A, B) %>%
filter(start >= onset, stop <= end)
head(A_merged, 15)
# A tibble: 15 x 6
ID start stop onset end treat
<fct> <int> <int> <dbl> <dbl> <dbl>
1 X 0 1 0 5 1
2 X 1 2 0 5 1
3 X 2 3 0 5 1
4 X 3 4 0 5 1
5 X 4 5 0 5 1
6 X 5 6 5 10 0
7 X 6 7 5 10 0
8 X 7 8 5 10 0
9 X 8 9 5 10 0
10 X 9 10 5 10 0
11 X 10 11 10 15 1
12 X 11 12 10 15 1
13 X 12 13 10 15 1
14 X 13 14 10 15 1
15 X 14 15 10 15 1
发布于 2020-04-24 11:38:36
我们可以使用模糊连接:
fuzzyjoin::fuzzy_left_join(A, B,
by = c('ID' = 'ID', 'start' = 'onset', 'stop' = 'end'),
match_fun = list(`==`, `>=`, `<=`))
# ID.x start stop ID.y onset end treat
#1 X 0 1 X 0 5 1
#2 X 1 2 X 0 5 1
#3 X 2 3 X 0 5 1
#4 X 3 4 X 0 5 1
#5 X 4 5 X 0 5 1
#6 X 5 6 X 5 10 0
#7 X 6 7 X 5 10 0
#8 X 7 8 X 5 10 0
#9 X 8 9 X 5 10 0
#10 X 9 10 X 5 10 0
#11 X 10 11 X 10 15 1
#12 X 11 12 X 10 15 1
#13 X 12 13 X 10 15 1
#14 X 13 14 X 10 15 1
#15 X 14 15 X 10 15 1
#....
#...
如果需要,您可以只对一个ID
列执行select
操作。
https://stackoverflow.com/questions/61400549
复制相似问题