Используйте ifelse () для выявления противоречивых ответов в данных - PullRequest
0 голосов
/ 03 октября 2018

У меня есть длинный формат данных с ответами на повторяющийся вопрос о статусе полового созревания vb_, задаваемый примерно раз в год в возрасте 9, 10, 11, 13, 14, 15, 16 и 17 лет.

Каждыйучастников года просили оценить их развитие от 1 до 5, из которых 1 был наименее развитым, а 5 - наиболее развитым.

Я хотел бы использовать R ifelse() для определения противоречивых ответов, то есть тех, которые сообщают о стадии в один год, который ниже, чем в любом из предыдущих лет.

Вот некоторые поддельные примеры данныхна 20 человек:

vb <- structure(list(id = c(1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 2L, 2L, 
                        2L, 2L, 2L, 2L, 2L, 2L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 4L, 4L, 
                        4L, 4L, 4L, 4L, 4L, 4L, 5L, 5L, 5L, 5L, 5L, 5L, 5L, 5L, 6L, 6L, 
                        6L, 6L, 6L, 6L, 6L, 6L, 7L, 7L, 7L, 7L, 7L, 7L, 7L, 7L, 8L, 8L, 
                        8L, 8L, 8L, 8L, 8L, 8L, 9L, 9L, 9L, 9L, 9L, 9L, 9L, 9L, 10L, 
                        10L, 10L, 10L, 10L, 10L, 10L, 10L, 11L, 11L, 11L, 11L, 11L, 11L, 
                        11L, 11L, 12L, 12L, 12L, 12L, 12L, 12L, 12L, 12L, 13L, 13L, 13L, 
                        13L, 13L, 13L, 13L, 13L, 14L, 14L, 14L, 14L, 14L, 14L, 14L, 14L, 
                        15L, 15L, 15L, 15L, 15L, 15L, 15L, 15L, 16L, 16L, 16L, 16L, 16L, 
                        16L, 16L, 16L, 17L, 17L, 17L, 17L, 17L, 17L, 17L, 17L, 18L, 18L, 
                        18L, 18L, 18L, 18L, 18L, 18L, 19L, 19L, 19L, 19L, 19L, 19L, 19L, 
                        19L, 20L, 20L, 20L, 20L, 20L, 20L, 20L, 20L), age = c(9L, 10L, 
                                                                              11L, 13L, 14L, 15L, 16L, 17L, 9L, 10L, 11L, 13L, 14L, 15L, 16L, 
                                                                              17L, 9L, 10L, 11L, 13L, 14L, 15L, 16L, 17L, 9L, 10L, 11L, 13L, 
                                                                              14L, 15L, 16L, 17L, 9L, 10L, 11L, 13L, 14L, 15L, 16L, 17L, 9L, 
                                                                              10L, 11L, 13L, 14L, 15L, 16L, 17L, 9L, 10L, 11L, 13L, 14L, 15L, 
                                                                              16L, 17L, 9L, 10L, 11L, 13L, 14L, 15L, 16L, 17L, 9L, 10L, 11L, 
                                                                              13L, 14L, 15L, 16L, 17L, 9L, 10L, 11L, 13L, 14L, 15L, 16L, 17L, 
                                                                              9L, 10L, 11L, 13L, 14L, 15L, 16L, 17L, 9L, 10L, 11L, 13L, 14L, 
                                                                              15L, 16L, 17L, 9L, 10L, 11L, 13L, 14L, 15L, 16L, 17L, 9L, 10L, 
                                                                              11L, 13L, 14L, 15L, 16L, 17L, 9L, 10L, 11L, 13L, 14L, 15L, 16L, 
                                                                              17L, 9L, 10L, 11L, 13L, 14L, 15L, 16L, 17L, 9L, 10L, 11L, 13L, 
                                                                              14L, 15L, 16L, 17L, 9L, 10L, 11L, 13L, 14L, 15L, 16L, 17L, 9L, 
                                                                              10L, 11L, 13L, 14L, 15L, 16L, 17L, 9L, 10L, 11L, 13L, 14L, 15L, 
                                                                              16L, 17L), vb_ = c(1L, 1L, 1L, 3L, 4L, 4L, 4L, 5L, 2L, 2L, 3L, 
                                                                                                 4L, 5L, 5L, 5L, 5L, 2L, 3L, 3L, 3L, 4L, 4L, 4L, 5L, 2L, 1L, 3L, 
                                                                                                 4L, 4L, 5L, 5L, 5L, 2L, 2L, 1L, 3L, 4L, 3L, 4L, 4L, 1L, 1L, 1L, 
                                                                                                 3L, 4L, 4L, 5L, 5L, 1L, 1L, 2L, 4L, 4L, 4L, 5L, 5L, 2L, 2L, 2L, 
                                                                                                 4L, 5L, 4L, 4L, 5L, 2L, 2L, 1L, 4L, 5L, 5L, 5L, 5L, 1L, 2L, 3L, 
                                                                                                 4L, 5L, 5L, 4L, 5L, 1L, 1L, 1L, 4L, 4L, 5L, 5L, 5L, 1L, 1L, 1L, 
                                                                                                 1L, 4L, 4L, 4L, 4L, 1L, 1L, 3L, 4L, 4L, 4L, 5L, 5L, 1L, 1L, 1L, 
                                                                                                 4L, 4L, 5L, 5L, 5L, 2L, 2L, 2L, 2L, 4L, 4L, 5L, 5L, 2L, 3L, 3L, 
                                                                                                 4L, 4L, 5L, 5L, 5L, 1L, 1L, 2L, 2L, 4L, 5L, 5L, 5L, 1L, 1L, 1L, 
                                                                                                 3L, 3L, 4L, 5L, 5L, 1L, 1L, 1L, 2L, 4L, 4L, 4L, 4L, 1L, 1L, 1L, 
                                                                                                 2L, 4L, 4L, 4L, 4L)), class = "data.frame", row.names = c(NA, 
                                                                                                                                                           -160L), .Names = c("id", "age", "vb_"))

Ответы [ 2 ]

0 голосов
/ 03 октября 2018

Вот, пожалуйста.

vb <- vb[order(vb$id, vb$age),]

vb$decreasingdevelopment <- c(0, diff(vb$vb_))<0 #difference between this score and previous <0
vb$sameperson <- c(0, diff(vb$id))==0 #is this the same participant than previous

vb$inconsistency <- vb$decreasingdevelopment&vb$sameperson #ifelse(vb$devdiff&vb$sameperson, T, F)
which(vb$inconsistency)
#[1] 26 35 38 62 67 79

Обратите внимание, что использование ifelse() возможно, но не обязательно.

PS: для полноты ответа всегда следует использовать следующее:

vb$inconsistency_robust <- apply(vb, 1, function(x) length(which(vb$vb_>x["vb_"]&vb$age<x["age"]&vb$id==x["id"]))>0)
#x["decreasingdevelopment"]&x["sameperson"])
all.equal(which(vb$inconsistency_robust), which(vb$inconsistency))

#> which(vb$inconsistency_robust) 
#[1] 26 35 38 62 63 67 79
#> which(vb$inconsistency)
#[1] 26 35 38 62 67 79

Обратите внимание, как надежный метод обнаруживает все случаи несоответствий, в то время как мой более наивный ifelse() метод здесь сравнивает только строку со строкой.

0 голосов
/ 03 октября 2018

Если вы настаиваете на ifelse подходе, вы можете сделать:

vb <- vb[order(vb$id, vb$age), ]
vb$inconsistent <- ifelse(vb$id == lag(vb$id), 
                          ifelse(vb$vb_ < lag(vb$vb_), "inconsistent", ""), 
                          "")
vb$inconsistent[1] <-  ""

    id age vb_ inconsistent
1    1   9   1             
2    1  10   1             
3    1  11   1             
4    1  13   3             
5    1  14   4             
6    1  15   4             
7    1  16   4             
8    1  17   5             
9    2   9   2             
10   2  10   2             
11   2  11   3             
12   2  13   4             
13   2  14   5             
14   2  15   5             
15   2  16   5             
16   2  17   5             
17   3   9   2             
18   3  10   3             
19   3  11   3             
20   3  13   3             
21   3  14   4             
22   3  15   4             
23   3  16   4             
24   3  17   5             
25   4   9   2             
26   4  10   1 inconsistent
27   4  11   3             
...

Или один подход с dplyr:

library(dplyr)

vb %>% 
  group_by(id) %>% 
  arrange(id, age) %>% 
  mutate(vb_diff = vb_ - lag(vb_)) %>% 
  filter(vb_diff < 0)

# A tibble: 6 x 4
# Groups:   id [5]
     id   age   vb_ vb_diff
  <int> <int> <int>   <int>
1     4    10     1      -1
2     5    11     1      -1
3     5    15     3      -1
4     8    15     4      -1
5     9    11     1      -1
6    10    16     4      -1
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...