我有以下数据:
Group Subject Lab LabValue Visit Baseline Count
1 001 Lab1 10 Day 1 Y 1
1 001 Lab1 11 Day 2 2
1 001 Lab1 12 Day 30 3
1 002 Lab1 11 Day 1 Y 1
1 002 Lab1 12 Day 30 2
2 005 Lab1 9 Day 1 Y 1
2 005 Lab1 16 Day 2 2
2 005 Lab1 11 Month 1 3
2 006 Lab1 18 Day 1 Y 1
2 006 Lab1 10 Day 2 2
Run Code Online (Sandbox Code Playgroud)
我想创建两个表:
第一个表显示 Lab1 的基线值变化,计算访问时的平均值并使用该特定访问的新患者子集重新计算基线:
Visit NumberSubjects VisitMean BaselineMean MeanChangeFromBaseline
Baseline 4 12 12 .
Day 2 3 12.3 13 -0.67
Day 30 2 12 10.5 +1.5
Month 1 1 11 9 +2
Run Code Online (Sandbox Code Playgroud)
第二个表允许选择将最后一次访问的所有受试者在第 1 个月没有访问的情况下“推送”到第 1 个月行(即受试者 001、002 和 005):
Visit NumberSubjects VisitMean BaselineMean MeanChangeFromBaseline
Baseline 4 12 12 .
Month 1 4 11.25 12 -0.75
Run Code Online (Sandbox Code Playgroud)
(对于受试者 001 和 002,第 30 天的值变为第 1 个月的值;对于受试者 006,第 2 天的值变为第 1 个月的值)。
这很复杂,但我想看看是否有使用 dplyr 执行此操作的方法。
我相信我可以使用以下代码为每个主题选择最后一个值:
do.call("rbind",
by(df, INDICES=df$Subject, FUN=function(DF) DF[which.max(DF$count), ]))
Run Code Online (Sandbox Code Playgroud)
任何有关如何创建这两个表的见解将不胜感激。
这是我可能会如何处理这个问题。
编辑要解决Baseline给定缺少值的问题Subject,如 OP 在评论中所建议的,请使用第一个LabValue可用的(假设按 排序Visit)。此外,要解决给定的LabValueper倍数问题,请添加并使用第一个可用值。代码已更新,原始示例的输出应该相同。VisitSubjectgroup_by(Visit, Subject)slice(1)
对于表 1,您可以group_by(Subject)然后LabValue为每个主题添加一个额外的基线列。这将使按访问计算统计数据变得更容易。
library(tidyverse)
# Table 1
df %>%
group_by(Subject) %>%
mutate(Baseline = first(LabValue)) %>%
group_by(Visit, Subject) %>%
slice(1) %>%
group_by(Visit) %>%
summarise(NumberSubjects = n(),
VisitMean = mean(LabValue),
BaselineMean = mean(Baseline),
MeanChangeFromBaseline = VisitMean - BaselineMean)
Run Code Online (Sandbox Code Playgroud)
输出
# A tibble: 4 x 5
Visit NumberSubjects VisitMean BaselineMean MeanChangeFromBaseline
<chr> <int> <dbl> <dbl> <dbl>
1 Day_1 4 12 12 0
2 Day_2 3 12.3333 12.3333 0
3 Day_30 2 12 10.5 1.5
4 Month_1 1 11 9 2
Run Code Online (Sandbox Code Playgroud)
对于表 2,我建议使用类似的complete方法添加未为每个主题完成的数据收集访问的空行,然后fill进行“最后一次观察结转”。然后最新可用的LabValue将结转到第 1 个月。
# Table 2
df %>%
group_by(Subject) %>%
mutate(Baseline = first(LabValue)) %>%
ungroup() %>%
complete(Subject, Visit) %>%
group_by(Subject) %>%
fill(LabValue, Baseline, .direction = "down") %>%
filter(Visit == "Day_1" | Visit == "Month_1") %>%
group_by(Visit, Subject) %>%
slice(1) %>%
group_by(Visit) %>%
summarise(NumberSubjects =sum(!is.na(LabValue)),
VisitMean = mean(LabValue, na.rm = TRUE),
BaselineMean = mean(Baseline, na.rm = TRUE),
MeanChangeFromBaseline = VisitMean - BaselineMean)
Run Code Online (Sandbox Code Playgroud)
输出
# A tibble: 2 x 5
Visit NumberSubjects VisitMean BaselineMean MeanChangeFromBaseline
<chr> <int> <dbl> <dbl> <dbl>
1 Day_1 4 12 12 0
2 Month_1 4 11.25 12 -0.75
Run Code Online (Sandbox Code Playgroud)