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



我有一个长形式的纵向数据集,长度约为 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",将每个ID分配到规范中使用的年龄和教育组。现在我想利用这些列,将其与上面 excel 文件的行和列相匹配。动机之一是创建一个代码,可以使用我的数据的测试分数进行进一步研究。

我认为您的ifelse语句应该可以正常工作,但我肯定会导入 Excel 文件而不是硬编码它,尽管您可能需要稍微不同地构建它。我会像数据集一样构建它,包括性别、Edu、年龄、平均值、SD、-1.5SD 等列,将其导入 R,然后在+Edu+Age 上做一个左外连接:

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

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

如果我理解正确,OP 希望在他的数据集中标记某种类型的异常值。因此,这里有两个任务:

  1. 计算每组sex、年龄类别agecat和 edu 类别edcat的统计信息mean(score)sd(score)和截止值mean(score) - 1.5 * sd(score)
  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)

最新更新