根据R中的规范数据添加一列

时间:2019-02-19 14:50:33

标签: r norm

我有一个长格式的纵向数据集,长度大约为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

我想创建一个新列“ cutoff”,其值为“ Normal”或“ Impaired”,因为我的结果数据“ score”具有一个截止分数,表示根据规范存在损害。根据性别,教育程度(Edu)和年龄,该规范由不同的-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”,将每个ID分配给该规范中使用的年龄和教育程度。现在,我想利用这些列,使其与上面的excel文件的行和列匹配。动机之一是使用我的数据的测试成绩创建一个可用于进一步研究的代码。

2 个答案:

答案 0 :(得分:0)

我认为您的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)

然后您可以直接比较各列。

答案 1 :(得分:0)

如果我理解正确,OP将在其数据集中标记某种类型的离群值。因此,这里有两个任务:

  1. mean(score),年龄类别sd(score)和edu类别{{1}的每组计算统计信息mean(score) - 1.5 * sd(score)sex和截止值agecat }}。
  2. 找到edcat低于特定组的临界值的所有行。

hannes101已经提到,第二步可以通过非等额联接来实现。

score
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

数据

OP的样本数据集已进行了一组修改以进行演示。

   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