【发布时间】:2020-02-10 12:40:42
【问题描述】:
跟进this question,我正在尝试增加一层难度。
我有一个看起来像这样的data.frame:
> set.seed(123)
> mydf <- data.frame(Marker=rep(c('M1','M2'),each=15),
+ Patient=rep(rep(c('P1','P2','P3'),each=5),2),
+ Value=sample(1:1000, 30, replace = F))
> mydf
Marker Patient Value
1 M1 P1 288
2 M1 P1 788
3 M1 P1 409
4 M1 P1 881
5 M1 P1 937
6 M1 P2 46
7 M1 P2 525
8 M1 P2 887
9 M1 P2 548
10 M1 P2 453
11 M1 P3 948
12 M1 P3 449
13 M1 P3 670
14 M1 P3 566
15 M1 P3 102
16 M2 P1 993
17 M2 P1 243
18 M2 P1 42
19 M2 P1 323
20 M2 P1 996
21 M2 P2 872
22 M2 P2 679
23 M2 P2 627
24 M2 P2 972
25 M2 P2 640
26 M2 P3 691
27 M2 P3 530
28 M2 P3 579
29 M2 P3 282
30 M2 P3 143
我想要做的是,在 Marker 基础上(我的 ID 变量)为每个 Patient 组合(我的分组变量)运行 t.test。
根据对上述相关问题的一个答案,我知道如何一次为一个 Marker 执行此操作。
我可以对mydf 进行子集化并执行以下操作:
> params_list <- utils::combn(levels(mydf$Patient), 2, FUN = list)
> mydf0 <- subset(mydf, Marker=="M1")
> model_t <- purrr::map(.x = params_list,
+ .f = ~ t.test(formula = Value ~ Patient,
+ data = subset(mydf0, Patient %in% .x)))
> t_pvals <- purrr::map_dbl(.x = model_t, .f = "p.value")
> names(t_pvals) <- purrr::map_chr(.x = params_list, .f = ~ paste0(.x, collapse = "-vs-"))
> t_pvals
P1-vs-P2 P1-vs-P3 P2-vs-P3
0.3945742 0.5678729 0.7820905
现在我想以一种优雅的方式为mydf 中的所有标记 做这件事,我选择了data.table。
我尝试以下操作,但无法重现 Marker M1 的上述 pvalue 结果。
> group1 <- unlist(lapply(params_list, '[', 1))
> group2 <- unlist(lapply(params_list, '[', 2))
> mydt <- data.table::data.table(mydf)
> results_df <- as.data.frame(mydt[, list(group1= unlist(lapply(params_list, '[', 1)),
+ group2= unlist(lapply(params_list, '[', 2)),
+ pvalue= purrr::map_dbl(.x = purrr::map(.x = params_list,
+ .f = ~ stats::t.test(formula = Value ~ Patient, paired=FALSE,
+ data = subset(mydt, Patient %in% .x))), .f = "p.value") ),
+ by=list(Marker=Marker)])
> results_df
Marker group1 group2 pvalue
1 M1 P1 P2 0.8092365
2 M1 P1 P3 0.5156313
3 M1 P2 P3 0.2879954
4 M2 P1 P2 0.8092365
5 M2 P1 P3 0.5156313
6 M2 P2 P3 0.2879954
results_df 的结构正是我想要的,但是 pvalues 显然是错误的。 M1与上面测试中的不同,M1和M2相同,表示相同的数据子集在这两种情况下都使用。
我认为我应该在 subset 命令中为每个 Marker 设置子集,所以我这样做了:
> markers_list <- as.list(levels(mydf$Marker))
> mydt <- data.table::data.table(mydf)
> results_df <- as.data.frame(mydt[, list(group1= unlist(lapply(params_list, '[', 1)),
+ group2= unlist(lapply(params_list, '[', 2)),
+ pvalue= purrr::map_dbl(.x = purrr::map(.x = params_list, .y = markers_list,
+ .f = ~ stats::t.test(formula = Value ~ Patient, paired=FALSE,
+ data = subset(mydt, Patient %in% .x & Marker==.y))), .f = "p.value") ),
+ by=list(Marker=Marker)])
> results_df
Marker group1 group2 pvalue
1 M1 P1 P2 0.7337355
2 M1 P1 P3 0.6930669
3 M1 P2 P3 0.3788015
4 M2 P1 P2 0.7337355
5 M2 P1 P3 0.6930669
6 M2 P2 P3 0.3788015
我以为就是这样,但我仍然得到不正确的 pvalues,并且 M1 和 M2 相同(两者仍使用相同的数据子集)...
所以现在我一无所知......我在这里做错了什么?该怎么做?
谢谢!
【问题讨论】:
标签: r dataframe testing data.table purrr