R语言 数据争吵:在一个时间点的一年内获取数据

6za6bjd0  于 11个月前  发布在  其他
关注(0)|答案(1)|浏览(94)

我正在尝试使用R(tidyverse)来执行以下操作:
假设我有一个数据集,其中包含受试者ID、访视代码(例如,1到8次访视)、访视日期、人口统计学(年龄、性别等)和两个测试结果(测试A和测试B)。
测试A从研究开始时就开始进行,但不是每次访视都必须进行。测试B开始较晚(最常见于访视5,但有些人在其他访视时)。
我想做一个横截面数据集,对应于每个人第一次进行测试B的情况(对于大多数人来说,这是在访视5,但对于其他人来说,这将是另一次访问)。我还希望每个人都有一个测试A的分数,至少有1年(+/-)时,测试B完成(许多人会在考试B的同时有一个考试A的分数,但有些人没有一个测试A分数的访问与他们的第一个测试B分数说,我然后想采取最近的测试分数从另一次访问,只有当它是在一年的测试B分数)。
我看到人们使用这种方法发布作品,但您能帮助我弄清楚如何编写这种代码以从主数据集获取这种类型的数据集吗?
为了澄清这个问题,我举了一个简单的例子(沿着我希望得到的输出):

mydata <- data.frame(Id=c(1,1,1,1,1,1,1,1, 2,2,2,2,2,2,2,2, 3,3,3,3,3,3,3,3),
VISIT=c(1,2,3,4,5,6,7,8, 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, 0,1,2.1,3.2,3.9,5.1,6,7.1),
Score_A=c(10,9,9,8,7,10,10,8, 5,9,4,3,NA,13,14,18, 9,9,10,11,NA,14,12,13),
Score_B=c(NA,NA,NA,NA,100,NA,90,NA, NA,NA,NA,NA,80,NA,99,NA, NA,NA,NA,NA,75,NA,97,NA) )

字符串
MyData

desired_output <- data.frame(Id=c(1,2,3), Score_A=c(7,13,11), Score_B=c(100,80,75))


我尝试了以下方法,但它没有考虑+/- 1年,因此Person 2的Score_A为NA:

Q <- mydata %>% 
group_by(Id) %>% 
arrange(Time, .by_group = T) %>% 
filter(!is.na(Score_B)) %>% 
slice(1)


谢谢你,谢谢

nr9pn0ug

nr9pn0ug1#

下面是一个使用滚动连接的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 nearest Visit with score A
firstB[, c("Score_A", "Time_A") := scoreA[firstB, .(Score_A, Time), on = .(Id, VISIT), roll = "nearest"]]
# select wanted columns, possibility to control times A and B are within 1
firstB[, .(Id, Time_A, Score_A, Time_B = Time, Score_B)]

字符串
输出”

Id Time_A Score_A Time_B Score_B
1:  1    4.0       7    4.0     100
2:  2    3.1       3    4.1      80
3:  3    3.2      11    3.9      75

老答案

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

相关问题