Фрейм данных подмножества в R, значения строки фильтра dplyr в столбце A, а не NA в строке столбца B

У меня есть набор данных, состоящий из исследования временных рядов. Поскольку некоторые участники не появлялись в течение определенных дней, у них есть значения NA для остальной части массива данных, но определенные учебные дни были решающими, поэтому я пытаюсь подгруппировать свои данные для участников, которые не пропускают эти важные дни. Мой набор данных на самом деле очень большой, но вот общая структура:

fakedat <- data.frame(ID = c("A", "A", "A", "A", "B", "B", "B", "B", "C", "C", "C", "C", 
                          "D", "D", "D", "D", "E", "E", "E", "E", "F", "F", "F", "F"),
                           StudyDay = c(1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4, 
                                        1, 2, 3, 4),
                           Ab = c(10, NA, 15, 10, 10, 20, 10, NA, 10, 10, NA, 30, NA, NA, 15, NA, 10, 20,
                                  10, 30, NA, 10, NA, 20))

Теперь предположим, что было критически важно, что они появятся на 2 и 4 день, я попробовал разделить подмножества с помощью фильтрации dplyr следующим образом:

fakedat2 <- fakedat %>%
  dplyr::group_by(ID) %>%
  dplyr::filter(StudyDay %in% c(2, 4) & !is.na(Ab)) %>%
  dplyr:: ungroup()

РЕДАКТИРОВАТЬ: но вывод этого набора данных - это только список, если идентификаторы, имеющие 2 или 4, не являются значением NA. Мне нужно найти (в моих реальных данных) субъектов, у которых есть значения NA Ab в 4 конкретных учебных дня. Ответ, который я принял ниже, работает, но вам все еще интересно выполнить условную фильтрацию? Как и в SAS, вы можете кодировать IF Ab! = NA в (StudyDay = 2 AND StudyDay = 4) THEN ID .... или что-то в этом роде.


person jrokh    schedule 19.12.2020    source источник


Ответы (2)


Может быть, это достигнет вашей цели. Если у всех участников есть все StudyDay временные точки, и вы просто хотите посмотреть, не пропали ли они в дни 2 или 4, вы можете просто проверить Ab значения в эти временные точки в вашем filter. В этом случае ID будет опущен, если он равен NA как во 2-й, так и в 4-й дни (в этом примере - D).

В качестве альтернативы, если вы хотите, чтобы оба значения были доступны для дней 2 и 4, вы можете использовать & (AND) вместо | (OR).

library(dplyr)

fakedat %>%
  group_by(ID) %>%
  filter(!is.na(Ab[StudyDay == 2]) | !is.na(Ab[StudyDay == 4]))

Если у вас есть несколько дней, чтобы проверить, не пропущены ли они, вы можете использовать all и проверить значения для NA, где StudyDay %in% вектор необходимых дней, как показано ниже:

required_vals <- c(2, 4)

fakedat %>%
  group_by(ID) %>%
  filter(all(!is.na(Ab[StudyDay %in% required_vals])))

Вывод

   ID    StudyDay    Ab
   <chr>    <dbl> <dbl>
 1 A            1    10
 2 A            2    NA
 3 A            3    15
 4 A            4    10
 5 B            1    10
 6 B            2    20
 7 B            3    10
 8 B            4    NA
 9 C            1    10
10 C            2    10
11 C            3    NA
12 C            4    30
13 E            1    10
14 E            2    20
15 E            3    10
16 E            4    30
17 F            1    NA
18 F            2    10
19 F            3    NA
20 F            4    20
person Ben    schedule 19.12.2020
comment
Вы не только правы, но и из-за вашего ответа я понял, что мой код неправильный. Он предоставляет мне фрейм данных всех идентификаторов, где 2 не является NA, а 4 - нет. Ваш ответ дает мне фрейм данных, который мне нужен в образцах данных, но не мои фактические данные - у меня все еще были некоторые важные даты со значениями NA. Я изменился | to & `filter (! is.na (Ab [StudyDay == 2]) |! is.na (Ab [StudyDay == 4]) ', и, похоже, это то, что мне сейчас нужно. - person jrokh; 19.12.2020
comment
@jrokh Мне было интересно об этом ... и в первый раз, когда я опубликовал ответ, было & (И) вместо | (ИЛИ). Но я пытался соответствовать вашему выводу, как и предполагалось. Возникает вопрос - должны ли присутствовать 2 и 4 или только один из них. Мы можем отредактировать ответ или оставить его как есть с пояснением. - person Ben; 19.12.2020
comment
Попался - я отредактировал свой вопрос, чтобы люди могли видеть - я нигде не мог найти хорошего ответа на это). Да, это будет 2 И 4, так что я предполагаю, что мой код правильно сделал 2 ИЛИ 4? Сейчас у меня всего 4 свидания, но, возможно, в конечном итоге их будет намного больше. Есть ли стенография или мне нужно будет выписать StudyDay == x? - person jrokh; 19.12.2020
comment
@jrokh См. отредактированный ответ. Вы можете создать вектор необходимых дней, а затем использовать all в своем filter. Это проверяет значения Ab, чтобы убедиться, что не NA, где StudyDay включен в требуемый вектор. - person Ben; 19.12.2020

В base R мы можем сделать

subset(fakedat, ID %in% ID[StudyDay %in% c(2, 4) & !is.na(Ab)])

-выход

#    ID StudyDay Ab
#1   A        1 10
#2   A        2 NA
#3   A        3 15
#4   A        4 10
#5   B        1 10
#6   B        2 20
#7   B        3 10
#8   B        4 NA
#9   C        1 10
#10  C        2 10
#11  C        3 NA
#12  C        4 30
#17  E        1 10
#18  E        2 20
#19  E        3 10
#20  E        4 30
#21  F        1 NA
#22  F        2 10
#23  F        3 NA
#24  F        4 20

Или аналогичный вариант в dplyr

library(dplyr)
fakedat %>%
     filter(ID %in% ID[StudyDay %in% c(2, 4) & !is.na(Ab)])
person akrun    schedule 19.12.2020
comment
спасибо за ваш ответ, я допустил ошибку в своем первоначальном вопросе, который я исправил - я не осознавал, что [StudyDay %in% c(2, 4) & !is.na(Ab)]) возвращал субъектов, пока у них не было NA ни на 2, ни на 4, не по крайней мере на 1. Его Решение, помимо того, что не нужно было записывать все дни (их могло быть несколько), заключалось в создании вектора required, оба работали и имели ту же структуру, что и ваш. Могу ли я проверить, что это решение, потому что это было просто на вопрос, который я задал неправильно? Спасибо за вашу помощь! - person jrokh; 19.12.2020