создать переменную на основе условий с другим набором данных в R - PullRequest
2 голосов
/ 24 апреля 2020

Я пытаюсь создать переменную на основе условий с другим набором данных. У меня есть два набора данных, 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

Итак, Х получал лечение до 5 дней. Через 5 дней Х не получал лечения и через 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 голосов
/ 24 апреля 2020
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
0 голосов
/ 24 апреля 2020

Мы можем использовать нечеткие объединения:

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, если это необходимо.

0 голосов
/ 24 апреля 2020

Мы можем использовать неэквивалентное объединение от 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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...