Кодирование изменения последовательности в R - PullRequest
0 голосов
/ 06 ноября 2019

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

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

    id <-       c(1,1,1, 2,2,2, 3,3, 4,4, 5,5,5,5, 6,6,6, 7, 8,8, 9,9, 10,10)
item.id <-  c(1,1,2, 1,1,1 ,1,1, 1,2, 1,2,2,2, 1,1,1, 1, 1,2, 1,1, 1,1)
sequence <- c(1,2,1, 1,2,3, 1,2, 1,1, 1,1,2,3, 1,2,3, 1, 1,1, 1,2, 1,2)
score <-    c(0,0,0, 0,0,1, 2,0, 1,1, 1,0,1,1, 0,0,0, 1, 0,2, 1,2, 2,1)

data <- data.frame("id"=id, "item.id"=item.id, "sequence"=sequence, "score"=score)
> data
   id item.id sequence score
1   1       1        1     0
2   1       1        2     0
3   1       2        1     0
4   2       1        1     0
5   2       1        2     0
6   2       1        3     1
7   3       1        1     2
8   3       1        2     0
9   4       1        1     1
10  4       2        1     1
11  5       1        1     1
12  5       2        1     0
13  5       2        2     1
14  5       2        3     1
15  6       1        1     0
16  6       1        2     0
17  6       1        3     0
18  7       1        1     1
19  8       1        1     0
20  8       2        1     2
21  9       1        1     1
22  9       1        2     2
23 10       1        1     2
24 10       1        2     1

id представляет для каждого студента, item.idпредставляет вопросы, которые задают ученики, sequence - это номер попытки для каждого item.id, а score - это оценка за каждую попытку, принимая 0,1 или 2. Учащиеся могут изменить свои ответы.

Для item.id внутри каждого id я хочу создать переменную (status), посмотрев на последние две последовательности (изменения):

a) assign "WW" for those who changed from wrong to wrong (0 to 0),
b) assign "WR" for those who changed to increasing score (0 to 1, or 1 to 2),
c) assign "RW" for those who changed to decreasing score (2 to 1, 2 to 0, or 1 to 0 ), and
d) assign "RR" for those who changed from right to right (1 to 1, 2 to 2).

изменение оценки от 0 до 1 или от 0 до2 или от 1 до 2 считаются правильными (правильными) изменениями, в то время как изменение оценки с 1 на 0 или от 2 до 0 или от 2 до 1 считаются неправильными (неправильными) изменениями.

Если для item.id имеется только одна попытка *как в id = 7, тогда status должно быть "one.right". Если score было 0, то оно должно быть "one.wrong". Между тем, score считается right, когда оно равно 1 или 2, score считается неправильным, когда оно равно 0.

желаемый результат будет в случаях:

 > desired
     id item.id    status
  1   1       1        WW
  2   1       2 one.wrong
  3   2       1        WR
  4   3       1        RW
  5   4       1 one.right
  6   4       2 one.right
  7   5       1 one.right
  8   5       2        RR
  9   6       1        WW
  10  7       1 one.right
  11  8       1 one.wrong
  12  8       2 one.right
  13  9       1        WR
  14  10      1        RW

Основное различие между предыдущей версией вопроса состояло в том, что я не рассматривал изменения

a) from 1 to 2 as WR, instead, they were coded as RR,
b) from 2 to 1 as RW, instead, they were coded as WW.

Опять логика должна быть, если счет увеличивается, это должно быть WR, если оно уменьшается, оно должно быть RW.

Лучший ответ, который я получил, был:

library(dplyr)
library(purrr)
library(forcats)

data %>% 
  mutate(status = ifelse(score > 0, "R", "W")) %>% 
  group_by(id, item.id) %>% 
  filter(sequence == n() - 1 | sequence == n()) %>%  
  summarise(status = paste(status, collapse = "")) %>% 
  ungroup() %>% 
  mutate(status = fct_recode(status, "one.wrong" = "W", "one.right" = "R"))

Но мне нужно справиться с шаблонами уменьшения / увеличения счета.

Есть мнения? Спасибо!

1 Ответ

1 голос
/ 07 ноября 2019

Вот классификация каждой строки:

library(dplyr)
data = data %>%
  group_by(id, item.id) %>%
  mutate(diff = c(0, diff(score)),
         status = case_when(
           n() == 1 & score == 0 ~ "one.wrong",
           n() == 1 & score > 0 ~ "one.right",
           diff == 0 & score == 0 ~ "WW",
           diff == 0 & score > 0 ~ "RR",
           diff > 0 ~ "WR",
           diff < 0 ~ "RW",
           TRUE ~ "oops"
         ))
print.data.frame(data)
#    id item.id sequence score diff    status
# 1   1       1        1     0    0        WW
# 2   1       1        2     0    0        WW
# 3   1       2        1     0    0 one.wrong
# 4   2       1        1     0    0        WW
# 5   2       1        2     0    0        WW
# 6   2       1        3     1    1        WR
# 7   3       1        1     2    0        RR
# 8   3       1        2     0   -2        RW
# 9   4       1        1     1    0 one.right
# 10  4       2        1     1    0 one.right
# 11  5       1        1     1    0 one.right
# 12  5       2        1     0    0        WW
# 13  5       2        2     1    1        WR
# 14  5       2        3     1    0        RR
# 15  6       1        1     0    0        WW
# 16  6       1        2     0    0        WW
# 17  6       1        3     0    0        WW
# 18  7       1        1     1    0 one.right
# 19  8       1        1     0    0 one.wrong
# 20  8       2        1     2    0 one.right
# 21  9       1        1     1    0        RR
# 22  9       1        2     2    1        WR
# 23 10       1        1     2    0        RR
# 24 10       1        2     1   -1        RW

Затем мы можем суммировать ее, взяв последнее значение status:

summarize(data, status = last(status))
# # A tibble: 14 x 3
# # Groups:   id [10]
#       id item.id status   
#    <dbl>   <dbl> <chr>    
#  1     1       1 WW       
#  2     1       2 one.wrong
#  3     2       1 WR       
#  4     3       1 RW       
#  5     4       1 one.right
#  6     4       2 one.right
#  7     5       1 one.right
#  8     5       2 RR       
#  9     6       1 WW       
# 10     7       1 one.right
# 11     8       1 one.wrong
# 12     8       2 one.right       
# 13     9       1 WR       
# 14    10       1 RW    

Это соответствует вашему желаемому результату.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...