考虑以下数据/示例。每个数据集包含多个样本,具有一个观察值和一个估计值:
library(tidyverse)
library(broom)
data = read.table(text = '
dataset sample_id observation estimate
A A1 4.8 4.7
A A2 4.3 4.5
A A3 3.1 2.9
A A4 2.1 2
A A5 1.1 1
B B1 4.5 4.3
B B2 3.9 4.1
B B3 2.9 3
B B4 1.8 2
B B5 1 1.2
', header = TRUE)
我想为每个数据集计算一个线性模型,以消除观察和估计之间的任何线性偏差,并获得原始值旁边的拟合值:
data %>%
group_by(dataset) %>%
do(lm(observation ~ estimate, data = .) %>% augment)
但是,这样做是删除sample_id
列,我需要保留该列,以便根据该唯一 ID 继续使用此数据集进行计算:
# A tibble: 10 x 10
# Groups: dataset [2]
dataset observation estimate .fitted .se.fit .resid .hat .sigma .cooksd .std.resid
<fct> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
1 A 4.80 4.70 4.68 0.107 0.115 0.478 0.152 0.491 1.04
2 A 4.30 4.50 4.49 0.0996 -0.193 0.416 0.0609 0.957 -1.64
3 A 3.10 2.90 2.97 0.0693 0.135 0.201 0.156 0.120 0.976
4 A 2.10 2.00 2.11 0.0849 -0.00583 0.303 0.189 0.000444 -0.0452
5 A 1.10 1.00 1.15 0.120 -0.0508 0.602 0.180 0.206 -0.521
6 B 4.50 4.30 4.31 0.109 0.191 0.468 0.0597 1.20 1.65
7 B 3.90 4.10 4.09 0.100 -0.193 0.396 0.0844 0.798 -1.56
8 B 2.90 3.00 2.91 0.0713 -0.00630 0.201 0.195 0.000247 -0.0443
9 B 1.80 2.00 1.83 0.0898 -0.0275 0.319 0.193 0.0103 -0.210
10 B 1.00 1.20 0.964 0.125 0.0355 0.616 0.191 0.104 0.360
如何保留原始数据集中的附加列?
我以前看过这个用于折叠数据的答案nest
,但我仍然只能使用这种方法获取模型参数。我想我可以提取每个数据集的参数:
data %>%
group_by(dataset) %>%
nest() %>%
mutate(
mod = map(data, linear_adj_model),
pars = map(mod, tidy)
) %>%
unnest(pars) %>%
select(dataset, term, estimate) %>%
spread(term, estimate)
…这给了我这个:
# A tibble: 2 x 3
dataset `(Intercept)` estimate
* <fct> <dbl> <dbl>
1 A 0.196 0.955
2 B -0.330 1.08
…然后将其与原始数据左连接,然后mutate
每个estimate
都得到线性调整的数据,但这似乎太复杂了。
我发现的另一个丑陋的技巧是将列作为虚拟变量添加到模型中:
data %>%
group_by(dataset) %>%
do(lm(observation ~ estimate + 0 * sample_id, data = .) %>% augment)
是否有一个更简单(整洁)的解决方案,不涉及手动指定我要保留的变量?