Добавление столбца по данным нормы в R - PullRequest
0 голосов
/ 19 февраля 2019

У меня есть продольный набор данных в длинной форме длиной около 2800, всего около 400 участников.Вот образец моих данных.

#    ID  wave score sex age edu 
#1  1001 1   28     1 69  12
#2  1001 2   27     1 70  12
#3  1001 3   28     1 71  12
#4  1001 4   26     1 72  12
#5  1002 1   30     2 78   9
#6  1002 3   30     2 80   9
#7  1003 1   30     2 65  16
#8  1003 2   30     2 66  16
#9  1003 3   29     2 67  16
#10 1003 4   28     2 68  16
#11 1004 1   22     2 85   4
#12 1005 1   20     2 60   9
#13 1005 2   18     1 61   9
#14 1006 1   22     1 74   9
#15 1006 2   23     1 75   9
#16 1006 3   25     1 76   9
#17 1006 4   19     1 77   9

Я хочу создать новый столбец «срез» со значениями «Нормальный» или «Нарушенный», потому что в моих исходных данных «счет» есть показатель среза, указывающий на ухудшение в соответствии с нормой.Норма состоит из различных показателей -1SD (точка отсечения) в зависимости от пола, образования (год образования) и возраста.

Ниже я делаю то, что я сейчас делаю, проверяю файл Excel и выставляю соответствующий показатель отсечения в соответствии с тремя условиями.Прежде всего, я не уверен, создаю ли я правильный столбец.

data$cutoff <- ifelse(data$sex==1 & data$age<70
                  & data$edu<3
                  & data$score<19.91, "Impaired", "Normal")
data$cutoff <- ifelse(data$sex==2 & data$age<70
                  & data$edu<3
                  & data$score<18.39, "Impaired", "Normal")

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

Файл Excel имеет структуру, показанную ниже.

#      Sex  Male                      Female            
#60-69 Edu(yr)  0-3 4-6 7-12   13>=   0-3   4-6 7-12    13>=
#Age   Number   22  51  119    72     130   138 106     51
#      Mean   24.45 26.6 27.06 27.83  23.31 25.86   27.26   28.09
#      SD     3.03  1.89    1.8 1.53  3.28  2.55    1.85    1.44
#     -1.5SD' 19.92 23.27   23.76   24.8    18.53   21.81   23.91   25.15
#70-79 Edu(yr)  0-3 4-6 7-12   13>=   0-3   4-6 7-12    13>=
....

Я создал новые столбцы «agecat» и «educat», распределяя каждый идентификатор по возрасту и образованию, которые используются в норме.Теперь я хочу использовать эти столбцы, сопоставляя их со строками и столбцами файла Excel выше.Одним из мотивов является создание кода, который можно использовать для дальнейших исследований с использованием результатов тестов моих данных.

Ответы [ 2 ]

0 голосов
/ 20 февраля 2019

Если я правильно понимаю, ОП хочет отметить определенный тип выбросов в своем наборе данных.Итак, здесь есть две задачи:

  1. Вычислить статистику mean(score), sd(score) и предельное значение mean(score) - 1.5 * sd(score) для каждой группы sex, возрастной категории agecat и eduкатегория edcat.
  2. Найти все строки, где score ниже, чем предельное значение для конкретной группы.

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

library(data.table)

# categorize age and edu (left closed intervals)
mydata[, c("agecat", "educat") := .(cut(age, c(seq(0, 90, 10), Inf), right = FALSE),
                                    cut(edu, c(0, 4, 7, 13, Inf), right = FALSE))][]
# compute statistics
cutoffs <- mydata[, .(.N, Mean = mean(score), SD = sd(score), 
                      m1.5SD = mean(score) - 1.5 * sd(score)),
                  by = .(sex, agecat, educat)]

# non-equi update join
mydata[, cutoff := "Normal"]
mydata[cutoffs, on = .(sex, agecat, educat, score < m1.5SD), cutoff := "Impaired"][]

mydata
      ID wave score sex age edu  agecat   educat   cutoff
 1: 1001    1    28   1  69  12 [60,70)   [7,13)   Normal
 2: 1001    2    27   1  70  12 [70,80)   [7,13)   Normal
 3: 1001    3    28   1  71  12 [70,80)   [7,13)   Normal
 4: 1001    4    26   1  72  12 [70,80)   [7,13)   Normal
 5: 1002    1    30   2  78   9 [70,80)   [7,13)   Normal
 6: 1002    3    30   2  80   9 [80,90)   [7,13)   Normal
 7: 1003    1    33   2  65  16 [60,70) [13,Inf)   Normal
 8: 1003    2    32   2  66  16 [60,70) [13,Inf)   Normal
 9: 1003    3    31   2  67  16 [60,70) [13,Inf)   Normal
10: 1003    4    24   2  68  16 [60,70) [13,Inf) Impaired
11: 1004    1    22   2  85   4 [80,90)    [4,7)   Normal
12: 1005    1    20   2  60   9 [60,70)   [7,13)   Normal
13: 1005    2    18   1  61   9 [60,70)   [7,13)   Normal
14: 1006    1    22   1  74   9 [70,80)   [7,13)   Normal
15: 1006    2    23   1  75   9 [70,80)   [7,13)   Normal
16: 1006    3    25   1  76   9 [70,80)   [7,13)   Normal
17: 1006    4    19   1  77   9 [70,80)   [7,13)   Normal
18: 1007    1    33   2  65  16 [60,70) [13,Inf)   Normal
19: 1007    2    32   2  66  16 [60,70) [13,Inf)   Normal
20: 1007    3    31   2  67  16 [60,70) [13,Inf)   Normal
21: 1007    4    31   2  68  16 [60,70) [13,Inf)   Normal
      ID wave score sex age edu  agecat   educat   cutoff

В этом подготовленном примере есть только одна строка, которая удовлетворяет условиям "Impaired".

Аналогично, статистика довольно редко заполняется:

cutoffs
   sex  agecat   educat N     Mean       SD   m1.5SD
1:   1 [60,70)   [7,13) 2 23.00000 7.071068 12.39340
2:   1 [70,80)   [7,13) 7 24.28571 3.147183 19.56494
3:   2 [70,80)   [7,13) 1 30.00000       NA       NA
4:   2 [80,90)   [7,13) 1 30.00000       NA       NA
5:   2 [60,70) [13,Inf) 8 30.87500 2.900123 26.52482
6:   2 [80,90)    [4,7) 1 22.00000       NA       NA
7:   2 [60,70)   [7,13) 1 20.00000       NA       NA

Данные

Образец набора данных OP был изменен в одной группе длядемонстрация.

library(data.table)

mydata <- fread("
#    ID  wave score sex age edu 
#1  1001 1   28     1 69  12
#2  1001 2   27     1 70  12
#3  1001 3   28     1 71  12
#4  1001 4   26     1 72  12
#5  1002 1   30     2 78   9
#6  1002 3   30     2 80   9
#7  1003 1   33     2 65  16
#8  1003 2   32     2 66  16
#9  1003 3   31     2 67  16
#10 1003 4   24     2 68  16
#11 1004 1   22     2 85   4
#12 1005 1   20     2 60   9
#13 1005 2   18     1 61   9
#14 1006 1   22     1 74   9
#15 1006 2   23     1 75   9
#16 1006 3   25     1 76   9
#17 1006 4   19     1 77   9
#18 1007 1   33     2 65  16
#19 1007 2   32     2 66  16
#20 1007 3   31     2 67  16
#21 1007 4   31     2 68  16
", drop = 1L)
0 голосов
/ 19 февраля 2019

Я думаю, что ваши ifelse операторы должны работать нормально, но я бы определенно импортировал файл Excel, а не жестко кодировал его, хотя вам, возможно, придется структурировать его немного по-другому.Я бы структурировал его так же, как набор данных, со столбцами для Sex, Edu, Age, Mean, SD, -1.5SD и т. Д., Импортировал его в R, затем выполнил левое внешнее объединение для Sex + Edu + Age:

merge(x = long_df, y = norm_df, by = c("Sex", "Edu(yr)", "Age"), all.x = TRUE)

Тогда вы можете сравнить столбцы напрямую.

...