Как подсчитать количество наблюдений, которые были отрицательными, до получения положительного результата

#r #group-by #count

#r #группировка по #подсчет

Вопрос:

Я работаю с некоторыми клиническими данными, и я хотел бы подсчитать количество проведенных кем-то тестов, которые были «Не обнаружены» до того, как у них был «Обнаруженный» результат, и исключить всех, у кого никогда не было «обнаруженного» результата.

 ID <- c(1,1,2,2,3,3,3,4)
Specimen_Type <- c("NP", "NP", "Throat", "Throat", "NP", "Throat", "Throat", "NP")
RESULT_VAL <- c("Not Detected", "Detected", "Not Detected", "Detected", "Not Detected", "Not Detected", "Detected", "Not Detected")
RESULT_DATE <- c("6-1-2020", "6-10-2020","6-1-2020", "6-10-2020","6-1-2020", "6-10-2020", "6-20-2020", "6-1-2020")
Data_sum<- data.frame(ID, Specimen_Type, RESULT_VAL, RESULT_DATE)

 

Я хотел бы, чтобы результат выглядел так (или что-то вроде этого), потому что я также хотел бы видеть, сколько разных типов образцов использовалось для тестирования до получения положительного результата.

 ID     Number_of_tests_before_pos     Specimen_Type     
1            1                              NP
2            1                              Throat 
3            2                              NP,Throat
 

Ответ №1:

Вот базовый вариант R

 transform(
  aggregate(
    . ~ ID,
    cbind(
      subset(Data_sum,
        ave(RESULT_VAL == "Detected", ID, FUN = function(x) cumsum(x) == 0 amp; any(x)),
        select = c(ID, Specimen_Type)
      ),
      Number_of_tests_before_pos = 1
    ),
    c
  ),
  Number_of_tests_before_pos = lengths(Number_of_tests_before_pos)
)
 

предоставление

   ID Specimen_Type Number_of_tests_before_pos
1  1            NP                          1
2  2        Throat                          1
3  3    NP, Throat                          2
 

Ответ №2:

После группировки по ‘ID’, используйте match для получения индекса первого вхождения ‘Detected’ в ‘RESULT_VAL’ (‘i1’), если совпадения нет, по умолчанию возвращает NA , используйте эту информацию для удаления идентификаторов filter , затем мы используем summarise для получения количества ‘NotОбнаружено’ в подмножестве ‘RESULT_VAL’ до этого индекса, аналогично paste unique элементам ‘sample_type’ в данных подмножества

 library(dplyr)
Data_sum %>% 
   group_by(ID) %>% 
   mutate(i1 = match('Detected', RESULT_VAL)) %>% 
   filter(complete.cases(i1)) %>%
   summarise(Number_of_tests_before_pos = sum(RESULT_VAL[seq(i1[1])] == 
          'Not Detected'),
          Specimen_Type = toString(unique(Specimen_Type[seq(i1[1])])),
           .groups = 'drop')
 

-вывод

 # A tibble: 3 x 3
#     ID Number_of_tests_before_pos Specimen_Type
#  <dbl>                      <int> <chr>        
#1     1                          1 NP           
#2     2                          1 Throat       
#3     3                          2 NP, Throat   
 

Или мы можем использовать cumsum логический вектор для выполнения filter редактирования

 Data_sum %>% 
     group_by(ID) %>% 
     filter(cumsum(RESULT_VAL == 'Detected') < 1,
            any(RESULT_VAL == 'Detected')) %>%
     summarise(Number_of_tests_before_pos = sum(RESULT_VAL == 'Not Detected'),
               Specimen_Type = toString(unique(Specimen_Type)), .groups = 'drop')
# A tibble: 3 x 3
#     ID Number_of_tests_before_pos Specimen_Type
#  <dbl>                      <int> <chr>        
#1     1                          1 NP           
#2     2                          1 Throat       
#3     3                          2 NP, Throat   
 

Ответ №3:

Вы можете сначала удалить все ID , что не имеет 'Detected' in RESULT_VAL , подсчитать количество строк до 'Detected' и объединить Specimen_Type в строку, разделенную одной запятой.

 library(dplyr)

Data_sum %>%
  group_by(ID) %>%
  filter(any(RESULT_VAL == 'Detected')) %>%
  summarise(n = match('Detected', RESULT_VAL) - 1, 
            Specimen_Type = toString(Specimen_Type[1:n]))

#    ID     n Specimen_Type
#  <dbl> <dbl> <chr>        
#1     1     1 NP           
#2     2     1 Throat       
#3     3     2 NP, Throat