我有一个长格式的纵向数据集,长度大约为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文件的行和列匹配。动机之一是使用我的数据的测试成绩创建一个可用于进一步研究的代码。
答案 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将在其数据集中标记某种类型的离群值。因此,这里有两个任务:
mean(score)
,年龄类别sd(score)
和edu类别{{1}的每组计算统计信息mean(score) - 1.5 * sd(score)
,sex
和截止值agecat
}}。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