根据条件与R中的其他数据集创建变量

时间:2020-04-24 03:20:44

标签: r mutate

我正在尝试根据其他数据集的条件创建变量。我有两个数据集AB

A是一段时间内的患者状态寄存器。它是按天注册的。 B是患者是否接受治疗的时间表。

我要创建一个变量,该变量指示患者是否基于计划(即B数据集)在A数据集中接受治疗。

例如,我有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

我尝试了使用dplyr函数的mutate软件包。

A%>%mutate(
treat=
case_when(
ID==B$ID & B$onset <= start & start < B$end ~ B$treat,
TRUE~0)

但是它返回了错误。因为两个数据集的行数不相等。

如何解决这个问题?

3 个答案:

答案 0 :(得分:0)

我们可以使用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

答案 1 :(得分:0)

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

答案 2 :(得分:0)

我们可以使用模糊连接:

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
#....
#...

然后,如果需要,您只能select一列ID