我正在尝试使用 R (tidyverse) 执行类似以下操作:
假设我有一个数据集,其中包含主题 ID、访问代码(例如 1 到 8 次访问)、访问日期、人口统计数据(年龄、性别等)以及两个测试结果(测试 A 和测试 B)。
从研究开始就进行测试 A,但并非每次就诊时都需要进行。测试 B 稍后开始(最常见的是在第 5 次就诊,但也有一些人在其他就诊)。
我想制作一个与每个人第一次执行测试 B 相对应的横截面数据集(对于大多数人来说是在访问 5,但对于其他人来说这将是另一次访问)。我还希望每个人的测试 A 分数至少与测试 B 完成后 1 年 (+/-) 相同(很多人会在测试 B 的同时获得测试 A 分数,但有些人则不会)如果他们的第一次测试 B 分数没有获得该次访问的测试 A 分数,那么我就想从另一次访问中获取最接近的测试分数(前提是该分数是在测试 B 分数的一年内)。
我看到人们使用这种方法发布作品,但是你能帮我弄清楚如何编码以从主数据集中获取此类数据集吗?
为了澄清这个问题,我整理了一个简单的例子(以及我希望得到的期望输出应该是什么):
mydata <-
data.frame(Id=c(1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2),
VISIT=c(1,2,3,4,5,6,7,8,1,2,3,4,5,6,7,8),
Time=c(0,1.1,1.9,3,4,5.1,6.1,6.9,0,.9,2.1,3.1,4.1,5,6.1,7.2),
Score_A=c(10,9,9,8,7,10,10,8,5,9,4,3,NA,13,14,18),
Score_B=c(NA,NA,NA,NA,100,NA,90,NA,NA,NA,NA,NA,80,NA,99,NA) )
desired_output <-
data.frame(Id=c(1,2),Score_A=c(7,13),Score_B=c(100,80))
我尝试了以下方法,但它没有考虑 +/- 1 年,因此第 2 个人的 Score_A 为 NA:
Q <- mydata %>%
group_by(Id) %>%
arrange(Time, .by_group = T) %>%
filter(!is.na(Score_B)) %>%
slice(1)
谢谢!
这是使用滚动连接的
data.table
方法。可以使用 dplyr-joins 来完成(查看 join_by()
上的帮助文件,但我觉得 data.table
更熟悉。
library(data.table)
# set to data.table format
setDT(mydata)
# get rows with first scoreB by Id
firstB <- mydata[!is.na(Score_B), .SD[1], by = .(Id)]
# all score_A values
scoreA <- mydata[!is.na(Score_A), ]
# rolling join on Visit + 1
firstB[, Score_A := scoreA[firstB, Score_A, on = .(Id, VISIT), roll = -1]]
# select wanted columns
firstB[, .(Id, Score_A, Score_B)]
# Id Score_A Score_B
# 1: 1 7 100
# 2: 2 13 80