0

我正在尝试分析纵向数据。每个科目至少有​​一次到我们的研究,最多 3 次。我需要比较每次就诊的分数,看看他们的治疗是否有助于减轻症状。

现在,我想设置列来指示主题是否有后续访问。

一栏表示受试者是否第二次访问,另一栏表示受试者是否第三次访问

我的数据集是什么样的

visit_id  subject_id   visit_number   Measure1    Measure2 ...
1         Subject1         1
2         Subject2         1
3         Subject1         2
4         Subject3         1
5         Subject1         3

我尝试过的编码

使用 sapply 按主题 ID 遍历所有访问,如果该主题有第二次访问和第三次访问,则填充列。

我也尝试了一个 for 循环,但在每种情况下,我都不确定如何告诉它循环遍历该主题的所有实例,然后选择要比较的项目(即是否存在特定访问号)

sapply(dat$subject_id, function(x) {

if(dat$visit_number == 2) {followup2 <- "yes"
}else {followup2 <- "no"}

if(dat$visit_number == 3) {followup3 <- "yes"
}else {followup3 <- "no"}
})

我希望我的数据集看起来像什么

visit_id  subject_id   visit_number     followup2  followup3
1         Subject1         1            yes         yes
3         Subject1         2            yes         yes
5         Subject1         3            yes         yes
2         Subject2         1            yes         no
6         Subject2         2            yes         no
4         Subject3         1            no          no

我打算使用类似的逻辑来遍历每个主题并比较他们在访问中的症状。比较访问 1 和 2,然后比较访问 2 和 3。

数据

dat <- read.table(header = TRUE, stringsAsFactors = FALSE,
text = "visit_id  subject_id   visit_number
1         Subject1         1
3         Subject1         2
5         Subject1         3
2         Subject2         1
6         Subject2         2
4         Subject3         1")
4

2 回答 2

1

由于您一遍又一遍地重复相同的任务,您可以创建一个函数来完成这项工作,然后循环遍历移动部件。

dat <- read.table(header = TRUE, stringsAsFactors = FALSE,
text = "visit_id  subject_id   visit_number
1         Subject1         1
3         Subject1         2
5         Subject1         3
2         Subject2         1
6         Subject2         2
4         Subject3         1")

visit此函数将按每个唯一值拆分,id并查看最大值visit是否大于num

f <- function(id, visit, num) {
  ave(visit, id, FUN = function(x) if (max(x) >= num) 'yes' else 'no')
}

制作一些测试用例以确保它正常工作

with(dat, f(subject_id, visit_number, 1))
# [1] "yes" "yes" "yes" "yes" "yes" "yes"
with(dat, f(subject_id, visit_number, 2))
# [1] "yes" "yes" "yes" "yes" "yes" "no" 
with(dat, f(subject_id, visit_number, 3))
# [1] "yes" "yes" "yes" "no"  "no"  "no" 

然后决定你需要循环什么。您还可以一次性为每个循环迭代在数据框中分配新列:

idx <- 2:3

dat[, paste0('followup', idx)] <- lapply(idx, function(x)
  f(dat$subject_id, dat$visit_number, x))

#   visit_id subject_id visit_number followup2 followup3
# 1        1   Subject1            1       yes       yes
# 2        3   Subject1            2       yes       yes
# 3        5   Subject1            3       yes       yes
# 4        2   Subject2            1       yes        no
# 5        6   Subject2            2       yes        no
# 6        4   Subject3            1        no        no
于 2019-10-29T06:19:00.450 回答
1

与其尝试一次性完成所有操作,不如将其分开为首先确定受试者是否进行了第二次(或第三次)访问,然后使用该数据添加一列。

做第一个:

subj_2_vist <- dat$subject_id[dat$visit_number==2]

现在subj_2_visit将是所有第二次访问的访问者的向量。然后您可以使用ifelse()创建新列:

dat$followup2 <- ifelse(dat$subject_id %in% subj_2_visit, "Yes", "No")

通过更改第一部分中的检查,同样可以用于三次访问。

于 2019-10-29T01:41:29.280 回答