Подсчет нескольких переменных отдельно во фрейме данных, имя переменной которого содержит последовательность - PullRequest
2 голосов
/ 07 апреля 2020

У меня есть огромный фрейм данных с несколькими именами переменных после последовательности. Чтобы упростить, я создал пример с 8 переменными, последние 5 переменных следуют последовательности в имени столбца: I5min_thre sh .118, I5min_thre sh .118.5, I5min_thre sh .119, I5min_thre sh .119.5, I5min_thre sh .120).

Последовательность в именах переменных является лишь примером и может расходиться, например, имя последовательности переменных может составлять от 60 до 180 с шагом 0,1 (в данном примере от 118 до 120 с шагом 0,5).

Воспроизводимый фрейм данных:

df<-data.frame(Event=c("yes","yes","yes","no","no","no","no","no","no"),
           mois=c(0.3,0.2,0.2,0.3,0.3,0.3,0.3,0.3,0.2),
           I_float=c(96.0,100.8,96.0,21.6,10.8,10.8,16.8,8.4,16.8),
           Imax.118=c(95.0,105.0,77.0,15.0,5.0,49.7,53.8,51.2,57.8),
           Imax.118.5=c(97.0,90.0,100.0,16.0,15.0,50.2,54.3,51.7,58.3),
           Imax.119=c(98.0,110.0,78.0,51.4,8.0,50.7,54.8,52.2,58.8),
           Imax.119.5=c(99.8,71.0,80.0,51.9,51.2,51.2,55.3,52.7,59.3),
           Imax.120=c(54.6,71.5,79.0,52.4,51.7,51.7,55.8,53.2,59.8))

Вот как выглядит фрейм данных:

enter image description here

Я хотел бы подсчитайте для каждого Imax следующие переменные и сохраните его в новом фрейме данных:

  • количество раз I_float> = Imax, если Event = yes, как переменная TP.
  • количество времена I_float
  • количество раз I_float> = Imax, если событие = нет, в качестве переменной FP.
  • количество раз, I_float

Полученный кадр данных должен выглядеть следующим образом, где Yintercept равен порядковому номеру, указанному в переменной Imax:

enter image description here

Пока мне удалось вычислить только TP, FN, TN и FP для 1 переменной , скажем, для переменной Imax.118, точно указав имя переменной в коде r (Imax.118) (первая строка предыдущего примера). Я не могу использовать метод вручную, так как у меня есть сотни переменных в реальном фрейме данных после последовательности имен.

Любая помощь будет высоко оценена.

Ответы [ 2 ]

2 голосов
/ 08 апреля 2020

Один из подходов - использовать pivot_longer, доступный в самой последней версии tidyr, для перевода в длинный формат.

Затем используйте case_when для сравнения и определения истинных / ложных положительных / отрицательных значений в каждой строке.

После суммирования по Yintercept и outcome вы можете использовать pivot_wider для создания окончательного результата.

df %>%
  pivot_longer(cols = starts_with("Imax"), names_to = "Yintercept", names_pattern = "^Imax.(\\d.+)",
               names_ptypes = list(Yintercept = double())) %>%
  mutate(outcome = case_when((I_float >= value) & (Event == "yes") ~ "TP",
                             (I_float < value) & (Event == "yes") ~ "FN",
                             (I_float >= value) & (Event == "no") ~ "FP",
                             (I_float < value) & (Event == "no") ~ "TN")) %>%
  group_by(Yintercept, outcome) %>%
  summarise(count = n()) %>%
  pivot_wider(id_cols = Yintercept, names_from = "outcome", values_from = "count", values_fill = list(count = 0))

Выход

# A tibble: 5 x 5
# Groups:   Yintercept [5]
  Yintercept    FN    FP    TN    TP
       <dbl> <int> <int> <int> <int>
1      118       1     2     4     2
2      118.5     2     1     5     1
3      119       2     1     5     1
4      119.5     1     0     6     2
5      120       0     0     6     3
2 голосов
/ 08 апреля 2020

Используя gather, мы можем сделать наши данные длинными, сохранить только цифры и точку исходных столбцов Imax, затем сгруппировать по столбцу Yintercept и суммировать количество строк, возвращающих TRUE для условия, указанные для столбцов TP, FN, TN и FP.

library(tidyverse)
df %>% 
  gather(Yintercept, val, -Event, -mois, -I_float) %>% 
  mutate(Yintercept = as.numeric(gsub("Imax\\.", "", Yintercept))) %>% 
  group_by(Yintercept) %>% 
  summarise(TP = sum(I_float > val & Event == "yes"),
            FN = sum(I_float < val & Event == "yes"),
            TN = sum(I_float < val & Event == "no"),
            FP = sum(I_float > val & Event == "no"))

  Yintercept    TP    FN    TN    FP
       <dbl> <int> <int> <int> <int>
1       118      2     1     4     2
2       118.     1     2     5     1
3       119      1     2     5     1
4       120.     2     1     6     0
5       120      3     0     6     0
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...