R Настройка данных с помощью Data.Table - PullRequest
1 голос
/ 04 мая 2020
data=data.frame("Student"=c(1,1,1,2,2,2,3,3,3,4,4,4,5,5,5),
       "Grade"=c(5,6,7,3,4,5,4,5,6,8,9,10,2,3,4),
       "Pass"=c(NA,0,1,0,1,1,0,1,0,0,NA,NA,0,0,0),
       "NEWPass"=c(0,0,1,0,1,1,0,1,1,0,0,0,0,0,0),
       "GradeNEWPass"=c(7,7,7,4,4,4,5,5,5,10,10,10,4,4,4),
       "GradeBeforeNEWPass"=c(6,6,6,3,3,3,4,4,4,10,10,10,4,4,4))

У меня есть data.frame, называемый data. В нем есть названия столбцов Student, Grade и Pass. Для этого я буду sh:

NEWPass: Take Pass и для каждого учащегося заполните значения NA с предыдущим значением. Если первое значение равно «NA», тогда ставьте ноль. Тогда это должен быть рабочий максимум.

GradeNEWPass: возьмите наименьшее значение оценки, которое студент получил в NEWPass. Если учащийся не получил один балл в NEWPass, это равняется максимальной оценке.

GradeBeforeNEWPass: примите значение оценки ДО того, как студент получит балл в NEWPass. Если учащийся не получил один в NEWPass, это соответствует максимальной оценке.

__ Попытки:

setDT(data)[, NEWPassTry := cummax(Pass), by = Student]
data$GradeNEWPass = data$NEWPassTry * data$Grade
data[, GradeNEWPass := min(GradeNEWPass), by = Student]

Ответы [ 2 ]

1 голос
/ 05 мая 2020

Правда, не очень, но ваша логика c включает такие слова, как "если есть ... для ученика" , так что это условно для группы, а не для строки.

library(magrittr) # just for %>% for breakout, not required
mydata %>%
  .[, NEWPass2 :=
        cummax(fifelse(seq_len(.N) == 1 & is.na(Pass), 0,
                       zoo::na.locf(Pass, na.rm = FALSE))), by = .(Student) ] %>%
  .[, GradeNEWPass2 :=
        if (any(NEWPass2 > 0)) min(Grade[ NEWPass2 > 0 ]) else max(Grade),
    by = .(Student) ] %>%
  .[, GradeBeforeNEWPass2 :=
        if (NEWPass2[1] == 0 && any(NEWPass2 > 0)) Grade[ which(NEWPass2 > 0)[1] - 1 ] else max(Grade),
    by = .(Student) ]
#     Student Grade Pass NEWPass GradeNEWPass GradeBeforeNEWPass NEWPass2 GradeNEWPass2 GradeBeforeNEWPass2
#  1:       1     5   NA       0            7                  6        0             7                   6
#  2:       1     6    0       0            7                  6        0             7                   6
#  3:       1     7    1       1            7                  6        1             7                   6
#  4:       2     3    0       0            4                  3        0             4                   3
#  5:       2     4    1       1            4                  3        1             4                   3
#  6:       2     5    1       1            4                  3        1             4                   3
#  7:       3     4    0       0            5                  4        0             5                   4
#  8:       3     5    1       1            5                  4        1             5                   4
#  9:       3     6    0       1            5                  4        1             5                   4
# 10:       4     8    0       0           10                 10        0            10                  10
# 11:       4     9   NA       0           10                 10        0            10                  10
# 12:       4    10   NA       0           10                 10        0            10                  10
# 13:       5     2    0       0            4                  4        0             4                   4
# 14:       5     3    0       0            4                  4        0             4                   4
# 15:       5     4    0       0            4                  4        0             4                   4

Я использую magrittr::%>% исключительно для разбивки на этапы вычислений, это не требуется.

0 голосов
/ 05 мая 2020

Мы можем использовать data.table методы. Сгруппированные по 'Student', создайте индекс ('i1'), где 'Pass' равен 1, а не NA, затем получите первую позицию 1 с which и head ('i2'), вычисляя при этом max из 'Grade' ('mx'), затем создайте три столбца на основе индексов ('v1' - получите совокупный максимум двоичного файла, 'v2' - if, есть any 1s, затем подмножество 'Grade' с индексом 'i2' или else, возвращающим 'mx', аналогично 'v3' - индекс вычитается 1, чтобы получить значение 'Grade'

library(data.table)    
setDT(data)[, c('NEWPass1', 'GradeNEWPass1', 'GradeBeforeNEWPass1') :={
              i1 <- Pass == 1 & !is.na(Pass)
              i2 <- head(which(i1), 1)
              mx <- max(Grade, na.rm = TRUE)
              v1 <- cummax(+(i1))
              v2 <- if(any(i1)) Grade[i2] else mx
              v3 <- if(any(i1)) Grade[max(1, i2-1)] else mx

            .(v1, v2, v3)}, Student]


data
#    Student Grade Pass NEWPass GradeNEWPass GradeBeforeNEWPass NEWPass1 GradeNEWPass1 GradeBeforeNEWPass1
# 1:       1     5   NA       0            7                  6        0             7                   6
# 2:       1     6    0       0            7                  6        0             7                   6
# 3:       1     7    1       1            7                  6        1             7                   6
# 4:       2     3    0       0            4                  3        0             4                   3
# 5:       2     4    1       1            4                  3        1             4                   3
# 6:       2     5    1       1            4                  3        1             4                   3
# 7:       3     4    0       0            5                  4        0             5                   4
# 8:       3     5    1       1            5                  4        1             5                   4
# 9:       3     6    0       1            5                  4        1             5                   4
#10:       4     8    0       0           10                 10        0            10                  10
#11:       4     9   NA       0           10                 10        0            10                  10
#12:       4    10   NA       0           10                 10        0            10                  10
#13:       5     2    0       0            4                  4        0             4                   4
#14:       5     3    0       0            4                  4        0             4                   4
#15:       5     4    0       0            4                  4        0             4                   4
...